將標量分解為行
經常需要在應用程序中傳送多值參數
雖然可以用 T
System
CLR TVF 提供了更有效的流實現
下面的代碼片段顯示了如何實現一個表值函數
// TVF that cracks a
// set of
public static ISqlReader GetStrings(SqlString str)
{
return (ISqlReader)new MySqlReader(str);
}
public class MySqlReader : ISqlReader
{
private string[] m_strlist;
private int m_iRow =
//The core methods
//Initialize list
public MySqlReader(SqlString str)
{
//Split input string if not database NULL;
//else m_strlist remains NULL
if (!str
{
m_strlist = str
}
}
// SECTION: Metadata related: Provide #
// result columns
public int FieldCount { get { return
public SqlMetaData GetSqlMetaData(int FieldNo)
{
if (FieldNo==
return new SqlMetaData(
else throw new NotImplementedException();
}
// SECTION: Row navigation
// false
// column is called
public bool Read()
{
//Return empty result set if input is DB NULL
//and hence m_strlist is uninitialized
if (m_strlist==null) return false;
m_iRow++;
if (m_iRow == m_strlist
return false;
return true;
}
//Column getters
//Implement Get<SqlTypeName> for each column produced by
//the TVF; in this case just one
public SqlChars GetSqlChars(int i)
{
if (i ==
return new SqlChars(m_strlist[m_iRow]);
else
throw new NotImplementedException();
}
//Methods not used by SqlServer omitted;
//Actual implementation should provide an empty
//implementation
} // public class MySqlReader
} // class StringFunctions;
假定 GetStrings 方法注冊為具有相同名稱的 TVF
CREATE PROCEDURE Insert_Order @cust_id int
nvarchar(
AS
BEGIN
INSERT LineItems
SELECT * FROM dbo
END
對數據進行自定義聚合
在許多情況下
將聚合編寫為用戶定義的聚合 (UDA)
使用 CLR 存儲過程編寫聚合
使用服務器端光標
讓我們在一個稱為 PRODUCT(int) 的簡單聚合函數的上下文中檢查這三種替代方法
作為用戶定義的聚合函數實現的 PRODUCT
下面是此函數的主干 C# 代碼示例
[SqlUserDefinedAggregate(Format
public struct Product
{
public void Accumulate(SqlInt
{
m_value *= Value;
}
public void Init() {
public void Merge(Product Group) {
public SqlInt
}
在定義類型
SELECT dbo
FROM tbl
GROUP BY col
作為使用 SqlDataReader 的托管存儲過程實現的 PRODUCT
可以創建存儲過程來執行查詢和循環訪問結果
[SqlProcedure]
public static void Product(out SqlInt
{
SqlCommand cmd = SqlContext
cmd
SqlDataReader r = cmd
bool first = true;
using (r)
{
while (r
{
if (first)
{
value = r
first = false;
}
else
{
value *= r
}
}
}
}
可以使用 EXEC 語句來調用這一過程
EXEC Product @p OUTPUT
作為使用光標的 T
可以創建 T
create procedure TSQL_ProductProc (@product int output)
as
begin
declare @sales int
declare c insensitive cursor for select intcolumn from tbl
open c
fetch next from c into @sales
if @@FETCH_STATUS =
set @product = @sales
while @@FETCH_STATUS =
begin
fetch next from c into @sales
set @product = @product * @sales
end
close c
deallocate c
end
決定是使用 UDA 還是使用其他某種解決方案來產生結果取決於幾個因素
可組合性要求
聚合算法細節
對副作用和數據訪問的需要
使用 UDA 的第一種方法在這三個選擇中可能提供最好的性能
可以用 UDA 方法編寫的有用的聚合的示例還包括
用戶定義的類型 (UDT)
現在
[SqlUserDefinedTypeAttribute(Format
public struct SimpleUdt: INullable
{
public override string ToString() {
public bool IsNull { get; }
public static SimpleUdt Null { get; }
public static SimpleUdt Parse(SqlString s) {
}
create type simpleudt from [myassembly]
create tab
From:http://tw.wingwit.com/Article/program/SQLServer/201311/22103.html