SQL Server 調用dll


 

 

   

今天要做數據導入的工作的時候,要導入員工表了。
有個字段叫 LoginName
而數據文件里面,沒有這個字段。

詢問一下主管,答復是 用姓名的拼音。 自己去網上去找個DLL來處理。

對於 中文漢字的拼音,這個以前倒是用 C# 調用 Simplified Chinese Pin-Yin Conversion Library 測試過。

 

不過實在不高興再去寫段程序,把數據從數據庫表里面讀取出來。
然后產生一個拼音的內容,最后在更新回數據庫去。

就考慮着,如果用 C# 寫個SQL Server 里面的 函數。

這樣直接在數據庫里面

UPDATE

SET
LoginName = GetNamePinYin(name);

一句話就一了百了啦。
以后又有新增的用戶,也可以這么折騰。

首先上網看看 C# 寫 SQL Server 的例子。


執行的前提
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO


然后在 VS2010 里面,創建一個 “Visual C# SQL CLR 數據庫項目”


首先創建下面這樣的函數 [代碼是 VS2010 自動產生的]

public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString Function1()
{
// 在此處放置代碼
return new SqlString("Hello");
}
};

 


然后,嘗試添加 Microsoft.International.Converters.PinYinConverter 的引用
發現無法添加額外的引用。只有少數的 類庫允許被引用。


折騰了一段時間以后, 最后發現

首先要在數據庫的 SQL Server Management Studio 中的 [可編程性] 下的 [程序集]中。
先把那個 ChnCharInfo.dll 加進去。

然后回到 Visual Studio 2010 中,就可以添加 ChnCharInfo.dll 這個引用了。

 

最后的C#代碼如下:


using System;
using System.Data;
using System.Text;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


using Microsoft.International.Converters.PinYinConverter;

public partial class UserDefinedFunctions
{

[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString GetPinYin(SqlString word)
{
string result = GetPinYn(word.ToString());
// 在此處放置代碼
return new SqlString(result);
}

///
/// 取得詞的拼音.
///
///
///
private static string GetPinYn(string word)
{
StringBuilder buff = new StringBuilder();
for (int i = 0; i < word.Length; i++)
{
// 依次取得每一個字的發音.
string onePinYin = GetOnePinYin(word[i]);
if (!String.IsNullOrEmpty(onePinYin))
{
// 拼音加入結果列表.
// 去掉最后一個聲調的數字.
buff.Append(onePinYin.Substring(0, onePinYin.Length - 1));
}
}
return buff.ToString();
}

///
/// 取得單個漢字的拼音.
///
///
///
private static string GetOnePinYin(char iChar)
{
// 初始化 Simplified Chinese Pin-Yin Conversion Library.
ChineseChar chineseChar = new ChineseChar(iChar);
// 取得拼音列表.
ReadOnlyCollection pinyin = chineseChar.Pinyins;
foreach (string pin in pinyin)
{
if (!String.IsNullOrEmpty(pin))
{
// 對於多音字,不判斷了,直接返回第一個發音.
return pin;
}
}
// 處理不了的情況下,返回空白.
return String.Empty;
}
};

 

寫完C#函數以后. 編譯通過完畢以后。
回到 SQL Server Management Studio 中的 [可編程性] 下的 [程序集]中。
先把這個編譯好的 SqlServerProject1.dll 加進去。

 

最后執行下面的 SQL 語句, 定義好存儲過程的函數。

CREATE FUNCTION[dbo].[GetNamePinYin]
(@word NVARCHAR (10))
RETURNS NVARCHAR (100)
AS
EXTERNAL NAME[SqlServerProject1].[UserDefinedFunctions].[GetPinYin]
go


SELECT dbo.GetNamePinYin('張三');
SELECT dbo.GetNamePinYin('李四');
go

ZHANGSAN
(1 行受影響)

LISI
(1 行受影響)

 

看上去是滿足預期了

不過最后實際使用的時候,還是發生了
在執行用戶定義例程或聚合 "GetNamePinYin" 期間出現 .NET Framework 錯誤:
System.NotSupportedException: The character is not in extended character set of
Simplified Chinese.
的異常。

回頭再去仔細看看,到底誰的名字這么奇怪的,呵呵。


 

 

以下是自己驗證過的, 出現以下錯誤時處理方法:

1.引入程序集后 , 右擊屬性,將權限集改為"無限制",否則會報:

請求“System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”類型的權限已失敗。”

 

2.引入程序集時,出現:

針對程序集 'SqlServerProject' 的 CREATE ASSEMBLY 失敗,因為程序集 'SqlServerProject' 未獲授權,不滿足 PERMISSION_SET = EXTERNAL_ACCESS。滿足以下兩個條件之一時將給程序集授權: 數據庫所有者(DBO)擁有 EXTERNAL ACCESS ASSEMBLY 權限,且數據庫具有 TRUSTWORTHY 數據庫屬性;或者,程序集已使用其對應登錄名具有 EXTERNAL ACCESS ASSEMBLY 權限的證書或非對稱密鑰加以簽名。
可以先執行以下語句:

--use master
--GRANT EXTERNAL ACCESS ASSEMBLY TO loginame

--ALTER DATABASE dbname SET TRUSTWORTHY ON

(dbname 為准備創建的程序集所在的數據庫,loginame 為該數據庫的所有者對應的登陸賬戶)

 

 

引入程序集后,新建存儲過程時,如下例:

CREATE PROCEDURE [dbo].[過程名]
@account [nvarchar](50),
@password [nvarchar](50),
@sms int OUTPUT,
@mms int OUTPUT
WITH EXECUTE AS N'dbo'
AS
EXTERNAL NAME [myself_pro].[StoredProcedures].[定義的方法名]
GO

S


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM