[SQL Server] ユーザ定義関数について

ユーザ定義関数について

SQL Serverでは、ユーザ定義関数と予め組み込まれたシステム関数がサポートされます。
今日の開発備忘録は、ユーザ定義関数です。

ユーザ定義関数は、もう少し細かく分けることができ、スカラー値関数とテーブル値関数と呼ばれています。
機能は、読んで字の如く「スカラー値」を返す関数と、「テーブル値」を返す関数となります。

どちらの関数も、CREATE FUNCTION句で関数名を宣言し、RETURNS句で戻り値を宣言し、RETURNで値を返します。
少しですが違うので具体的に見ていきます。

1)スカラー値関数
スカラー値関数は、MSDNではスカラー関数と記載されているのスカラー関数が正しいのかもしれません。
この関数の戻り値には、text、ntext、image、cursor、および timestamp 以外の任意のデータ型を指定できます。
多くは、数値(int)だったり名称(varchar)だったりだと思います。
先ほども書きましたがこの関数は、RETURNS 句で返す型を定義します。
RETURNで定義した型の単一のデータ値を返します。

具体的には、以下のような感じです。


--スカラー関数FN_TEST1が有れば消す
if OBJECT_ID (N'FN_TEST1',N'FN') is NOT NULL
DROP FUNCTION FN_TEST1
go

--テスト用テーブルT_FN_TESTが有れば消す
if OBJECT_ID (N'T_FN_TEST',N'U') is NOT NULL
Drop table T_FN_TEST
go

--テスト用テーブルT_FN_TEST作成&データセット
create table T_FN_TEST(
paramID int,
v_num int
)

insert into T_FN_TEST values (1,1)
insert into T_FN_TEST values (2,1)
insert into T_FN_TEST values (3,1)
insert into T_FN_TEST values (4,1)
insert into T_FN_TEST values (5,1)

go

--スカラー関数FN_TEST1を作成
CREATE FUNCTION FN_TEST1
(
@param1 int
)
RETURNS int
AS
BEGIN
DECLARE @ret int;

SELECT @ret = SUM(v_num)
FROM T_FN_TEST t
WHERE t.paramID >= @param1

IF (@ret IS NULL)
SET @ret = 0
RETURN @ret
END

go

--スカラー関数FN_TEST1の呼び出しテスト
declare @rv int
select @rv = [dbo].[FN_TEST1](3)
print @rv
go

--テスト用テーブルT_FN_TESTを消す
drop table T_FN_TEST

--スカラー関数FN_TEST1を消す
DROP FUNCTION FN_TEST1

2)テーブル値関数
ユーザー定義テーブル値関数は、table データ型を返します。
この関数もRETURNS句で戻り値を宣言しますが、
・インライン テーブル値関数
・複数のステートメントのテーブル値関数
で宣言とロジックが少し異なります。
ちなみに、table データ型の値を返すこの関数は、ビューとストアードプロシージャの中間のようなツールです。
ビューに比べると、まず同じようにFROM句に使用できる。ビューよりも高度SQLロジックが組める。
ストアードプロシージャに比べると、ストアードプロシージャはFROM句に使用できないので決定的に違います。
ただ、テーブル値関数は、既存のデータに関してUPDATE句は使用できませんしCREATE句も使用できません。
あくまでも参照用ってことですね。関数内で宣言したRETURNS句テーブルに関してはUPDATEもできます。

では、具体的な宣言方法へ

A.インライン テーブル値関数
RETURNS TABLEと宣言し、SELECT SQLを書くだけです。
この場合、SELECTで抽出したテーブルの定義がそのまま値として返ります。


--スカラー関数FN_TEST2が有れば消す
if OBJECT_ID (N'FN_TEST2',N'IF') is NOT NULL
DROP FUNCTION dbo.FN_TEST2
go

--テスト用テーブルT_FN_TESTが有れば消す
if OBJECT_ID (N'T_FN_TEST',N'U') is NOT NULL
Drop table T_FN_TEST
go

--テスト用テーブルT_FN_TEST作成&データセット
create table T_FN_TEST(
paramID int,
v_num int
)

insert into T_FN_TEST values (1,1)
insert into T_FN_TEST values (2,1)
insert into T_FN_TEST values (3,1)
insert into T_FN_TEST values (4,1)
insert into T_FN_TEST values (5,1)

go

--テーブル値関数FN_TEST2の作成
CREATE FUNCTION dbo.FN_TEST2
(
@param1 int
)
RETURNS TABLE
AS
RETURN
(
SELECT * from T_FN_TEST t
where t.paramID > @param1
)
go

--スカラー関数FN_TEST2の呼び出しテスト
select * from dbo.FN_TEST2(2)

select sum(v_num) from dbo.FN_TEST2(2)
--テスト用テーブルT_FN_TESTを消す
drop table T_FN_TEST

--スカラー関数FN_TEST2を消す
DROP FUNCTION FN_TEST2

B.複数のステートメントのテーブル値関数
複数の処理で返す値を整えていきます。
テーブルAから10行入れて、テーブルBから更に10行追加して、最後に一部の項目を更新するなどなど。
以下のように宣言します。


--スカラー関数FN_TEST3が有れば消す
if OBJECT_ID (N'FN_TEST3',N'TF') is NOT NULL
DROP FUNCTION dbo.FN_TEST3
go

--テスト用テーブルT_FN_TESTが有れば消す
if OBJECT_ID (N'T_FN_TEST',N'U') is NOT NULL
Drop table T_FN_TEST
go

--テスト用テーブルT_FN_TEST作成&データセット
create table T_FN_TEST(
tableID int,
R1 int,
R2 int,
R3 int,
R4 int,
R5 int,
R6 int
)

insert into T_FN_TEST values (1,1,1,1,1,1,1)
insert into T_FN_TEST values (2,1,1,1,1,1,1)
insert into T_FN_TEST values (3,1,1,1,1,1,1)
insert into T_FN_TEST values (4,1,1,1,1,1,1)
insert into T_FN_TEST values (5,1,1,1,1,1,1)

go

--テーブル値関数FN_TEST3の作成
CREATE FUNCTION dbo.FN_TEST3
(
@param1 int,
@param2 int,
@param3 int,
@param4 int
)
RETURNS @rtnTable TABLE
(
R1 int NOT NULL,
R2 int,
R3 int,
R4 int,
R5 int,
R6 int
)
AS
begin
insert into @rtnTable
SELECT t1.tableID, t1.R2, t1.R3, t1.R4, null, null from T_FN_TEST t1
where t1.tableID > @param1

update @rtnTable
set R5=R2 * @param2

insert into @rtnTable
SELECT t2.tableID, t2.R2, t2.R3, t2.R4, null, null from T_FN_TEST t2
where t2.tableID > @param3

update @rtnTable
set R6=R3 * @param4

return
end
go

--スカラー関数FN_TEST3の呼び出しテスト
select * from dbo.FN_TEST3(1,2,3,4)

select sum(R2) from dbo.FN_TEST3(1,2,3,4)
--テスト用テーブルT_FN_TESTを消す
drop table T_FN_TEST

--スカラー関数FN_TEST3を消す
DROP FUNCTION FN_TEST3

[ふと思ったこと] TeamViewerとは?

本日、久々にTeamViewerというアプリの話を耳にしました。

このアプリは、PCを遠隔操作するためのものです。
個人利用ならただで使用できます。

詳細な使用方法は、TeamViewerで検索するといろいろ出てくるので、困ることはないと思います。

なかなか、使用する機会はないのだけど、面白いアプリです。
ちなみに、iPhoneからでも遠隔操作できるみたいです。

[ASP.NET] FileUpload Web サーバー コントロールを使用してファイルをアップロードする

Webアプリケーションでファイルを取得するプログラムの備忘録です。

  1. FileUpload コントロールをページに追加します。
     セキュリティ上の理由から、ファイル名を FileUpload コントロールにあらかじめロードすることはできません。
  2. ページの Load イベントなどのイベントのハンドラでは、次の処理を行います。
    1. FileUpload コントロールがアップロードされたファイルを持つことを、その HasFile プロパティをテストすることで確認します。
    2. ファイルの名前または MIME の種類を確認し、受け入れるファイルをユーザーがアップロード済みであることを確認します。
        MIME の種類を確認するには、FileUpload コントロールの PostedFile プロパティとして公開されている HttpPostedFile オブジェクトを取得します。
        その後、ポストされたファイルの ContentType プロパティを確認することによって MIME の種類を取得できます。
    3. 指定した場所にファイルを保存します。
        HttpPostedFile オブジェクトの SaveAs メソッドを呼び出すことができます。
        または、HttpPostedFile オブジェクトの InputStream プロパティを使用してアップロードされたファイルをバイト配列またはストリームとして管理することもできます。

例)このコードではアップロードされたファイルの拡張子を、指定した拡張子リストと照らし合わせ、OKであれば保存処理へ進みます。
  保存は現在の Web サイトのUploadedImagesフォルダを指定しています。
  アップロードされたファイルは、クライアントコンピュータに存在していたときと同じ名前で保存されます。変更も可能です。
  HttpPostedFile オブジェクトのFileNameプロパティはファイルのクライアント コンピュータでの絶対パスを返すため、FileUpload コントロールのFileNameプロパティを使用します。

  また、クライアントから送信できるファイルの大きさは、既定サイズで4,096KB(4MB)です。
  この値は、MaxRequestLength値を変更することで変えられます。
    configSection.MaxRequestLength = 2048

  但し、MaxRequestLengthを超えたファイルを送った場合、ブラウザが真っ白になるかHTTPエラーになったはずです。。。
  なので、エラーや真っ白にしたくない場合、2Mまでとしたい場合は、余分に5M程度を設定しておき、一旦受け取った後PostedFile.ContentLengthでファイルサイズを確認し、
  2M以内なら保存、2Mを超えるようならエラーメッセージを出すなどのユーザインターフェースにした方が良いです。
  
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If IsPostBack Then

        Dim path As String = Server.MapPath(“~/UploadedImages/”)
        Dim fileOK As Boolean = False

        If FileUpload1.HasFile Then
            Dim fileExtension As String
            fileExtension = System.IO.Path.GetExtension(FileUpload1.FileName).ToLower()

            Dim allowedExtensions As String() = {“.jpg”, “.jpeg”, “.png”, “.gif”}
            For i As Integer = 0 To allowedExtensions.Length – 1
                If fileExtension = allowedExtensions(i) Then
                   fileOK = True
                End If
            Next

            If fileOK Then
                Try
                    FileUpload1.PostedFile.SaveAs(path & FileUpload1.FileName)
                    Label1.Text = “File uploaded!”
                Catch ex As Exception
                    Label1.Text = “File could not be uploaded.”
                End Try
            Else
                Label1.Text = “Cannot accept files of this type.”
            End If
        End If
    End If
End Sub

[JAVASCRIPT] PDFをWebブラウザに簡単に表示する方法

PDFをWebブラウザに簡単に表示する備忘録です。

  1. <embed src=”XXX.pdf”></embed>で表示する方法
  2. <object classid=”CLSID:CA8A9780-280D-11CF-A24D-444553540000″ src=”XXX.PDF”></object>で表示する方法

他にも有るかも知れませんが、とりあえず上の2つが簡単です。

ちなみに、動的にPDFファイルを変更して表示したい場合は、JAVASCRIPTを使う事になり、このタグのテーマにやっと沿えます^^;

例は、objectを利用して表示するPDFを動的に表示方法とembedを利用して利用してPDFを動的にする方法を載せています。
適宜簡単な説明が入っているのでなんとなくわかると思います。

ちなみに、objectを利用して表示する方はIEでしか動きません。
embedはIE,chrome共に動きました。

<html>
<head>
  <title>pdftest</title>
  <script type="text/javascript">
    onload = function () {
      var btn1 = document.getElementById("button1");
      btn1.onclick = function () {
        //Divの中身をクリア
        var element = document.getElementById("div_PDF").childNodes[0];
        if(element!=undefined){
          document.getElementById("div_PDF").removeChild(element);
        }

        //OBJECTタグを作成
        var obj = document.createElement('object');
        obj.setAttribute('id', 'objPdf');
        obj.setAttribute('classid', 'clsid:CA8A9780-280D-11CF-A24D-444553540000'); // PDFのクラスID(固定値)
        obj.setAttribute('style', 'width:500px; height:700px;');

        //PDFのソースを設定
        var param = document.createElement('param');
        param.setAttribute('name', 'src');
        param.setAttribute('value', 'http://www.pref.gifu.lg.jp/kurashi/zeikin/kenzei/zeimoku/kojin.data/kifukinkoujo.pdf');
        //param.setAttribute('value', 'PDFのURLを記述');
        obj.appendChild(param);

        //作成したOBJECTタグをDIVタグの中にセット
        var div = document.getElementById("div_PDF");
        div.appendChild(obj);
      }

      var btn2 = document.getElementById("button2");
      btn2.onclick = function () {
        //Divの中身をクリア
        var element = document.getElementById("div_PDF").childNodes[0];
        if (element != undefined) {
          document.getElementById("div_PDF").removeChild(element);
        }

        var emb = document.createElement('embed');
        emb.setAttribute('width', '500');
        emb.setAttribute('height', '700');
        emb.src = "https://www.nta.go.jp/shiraberu/ippanjoho/pamph/inshi/pdf/zeigaku_ichiran.pdf";
        //emb.src ="PDFのURLを記述";

        //作成したOBJECTタグをDIVタグの中にセット
        var div = document.getElementById("div_PDF");
        div.appendChild(emb);
      } 
    }
  </script>
</head>
<body>
  <form id="form1">
    <div id="div_PDF" style="width:520px; height:780px; background:#ccc"></div>
    <input type="button" id="button1" onclick="button1_click" value="object PDF表示" />
    <input type="button" id="button2" onclick="button1_click" value="embed PDF表示"/>
  </form>
</body>
</html>

[ASP.NET] Windows7でIIS Webサーバを利用する

今までは、Windows7でVS2010を使用してWebアプリを開発していた時、他のPCから確認する際はテストサーバに発行してから他のPCで確認する方法を取っていました。
今回、開発PCに直接アクセスするケースが想定されたため、Windows7のIISを利用することしにました。
開発PCに発行するという手も有ったのですが、アクセスしてきたPCの情報確認を取りたかったため、デバッグができる方がよいと考え、そのようにしました。

そこで、Windows7でVS2010からIISをWebサーバにしてデバッグを行う設定を開発備忘録としてメモっておきます。
といっても、実は、途中メモを取らなかったので。。。。

とりあえず、確実にしたことは、
1)IISのインストール
〔コントロールパネル〕→
〔プログラムと機能〕→
〔Windows機能の有効化または無効化〕→
インターネットインフォメーションサービス
デフォルト以外でチェックした項目
・IIS6と互換性のある管理→IISメタベースおよびIIS6構成との互換性
・World Wide Web サービス→ Windows認証

2)Windowsファイアウォールの設定
〔コントロールパネル〕→
〔Windowsファイアウォール〕→
〔Windowsファイアウォールを介したプログラムまたは機能を許可する〕
設定画面が表示されるので、右上の設定の変更ボタンをクリック
一覧の中からWorld Wide Web サービス(HTTP)を探し、許可する
下段のOKボタンをクリック

以上で、他のPCからでもIISへアクセスできるようになり、デバッグも可能となります。

[WinCDEmu] 仮想CD/DVDマウントできない

MSDNやTechNetのISOファイルをインストールする時にお世話になっているWinCDEnumですが、1ファイルだけマウントできない現象に見舞われました。。。

よくよく見ると、ファイル名がマウントできているファイルより長いのがわりました。
そこで、ファイル名を変更し、短くしたところ、マウントできるようになりました^^
良かった良かった^^

[SQLSERVER] SQL SERVER 2012

やっと、SQLSERVER2012をインストールしました。
まだ、使っていませんが、インストールに関してはノーマルインストールでしたのでストレスなくスムーズに出来ました。

使用する予定はしばらくないのですが、どんな感じか確かめるのが楽しみです。

そう言えば、インストールの内容なのか、インストール済のソフトウェアの構成なのか、途中でVisual Studio 2010のDVDを要求されました。なんでかな?

[ASP.NET] ASP.NETのセッションタイムアウトについて

ASP.NETのセッションタイムアウトについて

ASP.NETアプリケーションでは必要に応じて、実行時の状態(変数の値)を次回のポストバックの為にSessionプロパティに値を格納
していると思いますが、そのセッションのアイドル状態が何分続くと破棄するかを決めているのがセッションタイムアウトです。

セッションタイムアウトは以下のように指定することができます。

指定の仕方で優先が決まります。下位の設定は上位の設定で上書きされます。
単位は「分」です。

優先1:ページへの記述による設定
    影響範囲は、そのセッション中。ページ毎に上書きも可。もちろん上書き優先。
    aspxに記述        <% Session.Timeout = 120%>
    CodeBehind側に記述  Session.Timeout=120

優先2:global.asaxによる設定
    影響範囲:そのセッション
    Application_Startメソッドに記述
    ※Session_Startメソッド以降の記述は有効化どうか未検証。試した方教えてください。
    Session.Timeout=120

優先3:Web.configによる設定
    影響範囲:そのWebアプリケーション
    <sessionState mode=”InProc” timeout=”120″/>
    modeは、既定値はInProcですが、SQLServerやStateServerなど適宜変更して下さい。
    Offはセッション状態無効です。

優先4:Machine.Config
    影響範囲:マシン全体
 記述はWeb.configと同じ

※WebConfig及びMachine.configの既定の構成
 次の既定の <sessionState> 要素は、Machine.config ファイルまたはルートのWeb.configファイルでは明示的に構成されません。
 ただし、取得を行うと以下の値が返されます。すなわち既定の構成となっています。

 <sessionState
  mode=”InProc”
  stateConnectionString=”tcpip=127.0.0.1:42424″
  stateNetworkTimeout=”10″
  sqlConnectionString=”data source=127.0.0.1;Integrated Security=SSPI”
  sqlCommandTimeout=”30″
  customProvider=””
  cookieless=”UseCookies”
  cookieName=”ASP.NET_SessionId”
  timeout=”20″
  allowCustomSqlDatabase=”false”
  regenerateExpiredSessionId=”true”
  partitionResolverType=””
  useHostingIdentity=”true”>
  <providers>
    <clear />
  </providers>
 </sessionState>

 WebConfig及びMachine.configの既定値で「timeout=”20″ 」となっています。
 何も設定しないとセッションが20分で切れるのはこのためです。

※セッション timeout 構成設定は ASP.NET ページだけに適用されます。ASPページは影響しません。
※ちなみに、「Timeout プロパティを、525,600 分 (1 年) を超える値に設定することはできません。」だそうです。

[ASP.NET] NuGetにつて

NuGetについて

NuGetは、公開されているモジュールを簡単にダウンロード、インストールするパッケージ・マネージャ機能アプリケーションです。
少し言い換えるとNuGetは、「NuGet gallery」で公開されているソフトウェアやライブラリのパッケージを検索、インストール、更新、アンインストールなどを行うためのアプリケーションです。

例えば、公開されているWebアプリケーションを自分で作成しているWebアプリケーションに組み込みたい時に、公開されているWebアプリケーションをNuGetでインストールすると、他に作業を行うこと無く利用可能な環境にしてくれます。
手動でできるからNuGet利用しなくても良いというわけでなく、環境を適切にインストールし、参照パッケージに更新が有った場合も更新してくれるなど人が依るより確実に実施・管理してくれるのが特徴ですので、公開されているパッケージを利用したい場合は利用しない手はないです。

インストールや利用方法は、ネットで検索するといろいろ出てきますので、開発に携わってる方は覗くいて見ることをお勧めします。

Windows7 32bit 利用できないメモリをRamDisk化。。。と思ったら。。。

Windows7 32bit 利用できないメモリをRamDisk化。。。と思ったら。。。

Windows7 32bit 利用できないメモリをRamDisk化するには、いろいろ手があるみたいだけど、
Free Editionならタダだしー^^「VSuite Ramdisk」が良いみたいと思ったのですが。。。。

で、窓の杜から落とそうとしたら。
   http://www.forest.impress.co.jp/lib/sys/hardcust/virtualdrv/vsuiteramdsk.html
OSがWindows7は対象になっていないようですが??
でここ 「http://www.romexsoftware.com/en-us/index.html」 のDetailsで見ると、

Supported OS
 Supports Windows 2000, Windows XP, Windows 2003, Windows Vista, Windows 2008, Windows 7, Window  2008 R2.
 Supports both 32-bit and 64-bit of Windows OSs.
 note: Free Edition only supports Windows 2000/XP(32-bit)/2003(32-bit).

となっているではないですか(TT);

まぁ、慌てていないので、そのうちほかっておいた領域をRamDisk化したいと思います^^
とりあえず、失敗談でした・・・・