<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>昨天完成了一個最簡單的在數(shù)據(jù)庫中創(chuàng)建標量值函數(shù),今天主要完成表值函數(shù),存儲過程和用戶定義類型在和.NET結(jié)合下的使用方法.
1,表值函數(shù)
所謂表值函數(shù)就是說這個函數(shù)返回的結(jié)果是一個Table,而不是單個的值.
在.NET 中創(chuàng)建這樣的函數(shù),返回的結(jié)果是一個IEnumerable接口.這個接口非常靈活,所有.NET數(shù)組集合等都是實現(xiàn)了該接口的.下面我們舉一個簡單的例子來說明.
在VS2005中創(chuàng)建一個類Student,這個就是我們要返回的表的內(nèi)容,類下面有屬性int Age,string sName,DateTime Birthday,int SID;
然后在另外一個類UserFunction中寫入如下代碼:
[SqlFunction(FillRowMethodName
=
"
FillRow
"
)]
public
static
IEnumerableGetStudent()
{
Hashtablehash
=
new
Hashtable();
for
(
int
i
=
0
;i
<
3
;i
++
)
{
Students
=
new
Student();
s.SID
=
i;
...
hash.Add(i,s);
}
return
hash.Values;
}
public
static
void
FillRow(
object
obj,
ref
SqlInt32id,
ref
SqlStringname,
ref
SqlDateTimebir,
ref
SqlInt32age)
{
Students
=
(obj
as
Student);
id
=
s.SID;
name
=
s.sName;
bir
=
s.Birthday;
age
=
s.Age;
}
第一個屬性中指定FillRowMethodName就是為了將返回的IEnumerable接口中的數(shù)據(jù)進行轉(zhuǎn)換,將數(shù)據(jù)庫無法認識的集合轉(zhuǎn)換為數(shù)據(jù)庫人生的字段.下面的函數(shù)FillRow就是具體轉(zhuǎn)換的過程.
這樣寫完成以后,在數(shù)據(jù)庫那邊添加好這個程序集,然后就可以創(chuàng)建表值函數(shù)了:
create
function
BuildTable()
returns
table
(SID
int
,
[
sName
]
nvarchar
(
100
),Birthday
datetime
,Age
int
)
as
externalnameSQLFunction.
[
SQLFunction.UserFunction
]
.GetStudent
這兒就不用太多的解釋了,就是將名為SQLFunction的程序集中的[名字空間.類].方法添加到BuildTable函數(shù)中.
這兒需要說明一下就是數(shù)據(jù)庫中的類型和.NET中的類型的對應(yīng)問題.int,datetime就不說了,主要是.NET中的string,在數(shù)據(jù)庫中沒有string類型,在FillRow中指出了類型SqlString,而這個類型的對應(yīng)是nchar,nvarchar.這兒不能對應(yīng)char,varchar,我不知道為什么必須是對應(yīng)nchar的.所以上面我們寫的是[sName] nvarchar(100).
大功告成,測試一下,輸入語句select * from BuildTable()看看返回你的表沒有.
2.存儲過程
CLR存儲過程和CLR函數(shù)非常相似,不過有幾點更高的能力:
CLR存儲過程可以有一個返回值,也可以寫輸出參數(shù),可以返回消息給客戶程序,可以調(diào)用DDL和DML語句.
.NET創(chuàng)建存儲過程要編寫為靜態(tài)函數(shù),然后加上SqlProcedure屬性.
比如我們寫一個簡單的存儲過程
[SqlProcedure]
public
static
int
Add(
int
a,
int
b)
{
return
a
+
b;
}
然后在數(shù)據(jù)庫中寫入:
create
procedure
Add2Num
@a
int
,
@b
int
as
externalnameSQLFunction.
[
SQLFunction.UserFunction
]
.
[
Add
]
整個代碼我就不用解釋了,和前面創(chuàng)建函數(shù)一樣.
我們運行看看結(jié)果:
declare
@a
int
exec
@a
=
Add2Num
10
,
12
print
@a
3.用戶定義類型(UDT)
要創(chuàng)建UDT類必須符合"UDT規(guī)范",.NET中的約束如下:
他們必須帶SqlUserDefinedType 屬性
必須帶有Serializable屬性
必須實現(xiàn)INullable接口
必須博阿訇公開和靜態(tài)的Parse和ToString方法以用于轉(zhuǎn)換數(shù)據(jù)類型字符串或逆向轉(zhuǎn)換.
必須暴露數(shù)據(jù)元素為公開字段或公開屬性.
好,那我們就創(chuàng)建一個簡單的UDT復(fù)數(shù)類如下:
[Serializable]
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
public
class
Complex:INullable
{
bool
isNull
=
false
;
double
real,imag;
public
bool
IsNull
{
get
{
return
isNull;}
}
public
double
Real
{
get
{
return
real;}
set
{real
=
value;}
}
public
double
Imag
{
get
{
return
imag;}
set
{imag
=
value;}
}
public
override
string
ToString()
{
if
(isNull)
{
return
"
NULL
"
;
}
else
{
return
real
+
"
,
"
+
imag;
}
}
public
static
ComplexParse(SqlStrings)
{
if
(s
==
null
||
s.IsNull)
{
return
null
;
}
else
{
Complexc
=
new
Complex();
string
str
=
Convert.ToString(s);
string
[]st
=
str.Split(
'
,
'
);
c.real
=
Convert.ToDouble(st[
0
]);
c.imag
=
Convert.ToDouble(st[
1
]);
return
c;
}
}
}
編譯好,在數(shù)據(jù)庫中添加程序集后,我們運行如下代碼:
create
typeComplex
externalnameSQLFunction.
[
SQLFunction.Complex
]
這樣我們就創(chuàng)建好了用戶定義類型Complex.
數(shù)據(jù)庫事例代碼中有相關(guān)內(nèi)容,參見:
\Program Files\Microsoft SQL Server\90\Samples\Engine\Programmability\CLR\UserDefinedDataType
1,表值函數(shù)
所謂表值函數(shù)就是說這個函數(shù)返回的結(jié)果是一個Table,而不是單個的值.
在.NET 中創(chuàng)建這樣的函數(shù),返回的結(jié)果是一個IEnumerable接口.這個接口非常靈活,所有.NET數(shù)組集合等都是實現(xiàn)了該接口的.下面我們舉一個簡單的例子來說明.
在VS2005中創(chuàng)建一個類Student,這個就是我們要返回的表的內(nèi)容,類下面有屬性int Age,string sName,DateTime Birthday,int SID;
然后在另外一個類UserFunction中寫入如下代碼:























這樣寫完成以后,在數(shù)據(jù)庫那邊添加好這個程序集,然后就可以創(chuàng)建表值函數(shù)了:




這兒就不用太多的解釋了,就是將名為SQLFunction的程序集中的[名字空間.類].方法添加到BuildTable函數(shù)中.
這兒需要說明一下就是數(shù)據(jù)庫中的類型和.NET中的類型的對應(yīng)問題.int,datetime就不說了,主要是.NET中的string,在數(shù)據(jù)庫中沒有string類型,在FillRow中指出了類型SqlString,而這個類型的對應(yīng)是nchar,nvarchar.這兒不能對應(yīng)char,varchar,我不知道為什么必須是對應(yīng)nchar的.所以上面我們寫的是[sName] nvarchar(100).
大功告成,測試一下,輸入語句select * from BuildTable()看看返回你的表沒有.
2.存儲過程
CLR存儲過程和CLR函數(shù)非常相似,不過有幾點更高的能力:
CLR存儲過程可以有一個返回值,也可以寫輸出參數(shù),可以返回消息給客戶程序,可以調(diào)用DDL和DML語句.
.NET創(chuàng)建存儲過程要編寫為靜態(tài)函數(shù),然后加上SqlProcedure屬性.
比如我們寫一個簡單的存儲過程





然后在數(shù)據(jù)庫中寫入:




整個代碼我就不用解釋了,和前面創(chuàng)建函數(shù)一樣.
我們運行看看結(jié)果:



3.用戶定義類型(UDT)
要創(chuàng)建UDT類必須符合"UDT規(guī)范",.NET中的約束如下:
他們必須帶SqlUserDefinedType 屬性
必須帶有Serializable屬性
必須實現(xiàn)INullable接口
必須博阿訇公開和靜態(tài)的Parse和ToString方法以用于轉(zhuǎn)換數(shù)據(jù)類型字符串或逆向轉(zhuǎn)換.
必須暴露數(shù)據(jù)元素為公開字段或公開屬性.
好,那我們就創(chuàng)建一個簡單的UDT復(fù)數(shù)類如下:



















































這樣我們就創(chuàng)建好了用戶定義類型Complex.
數(shù)據(jù)庫事例代碼中有相關(guān)內(nèi)容,參見:
\Program Files\Microsoft SQL Server\90\Samples\Engine\Programmability\CLR\UserDefinedDataType
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
