托管代码编写mssql存储过程
参考:http://wenku.it168.com/d_000642903.shtml
打开vs,创建数据库项目,添加新项,选择sql clr c#, 选择存储过程。
样例:
[Microsoft.SqlServer.Server.SqlProcedure]
public static int mypro2(int id, string mc, out string err)
{
using (SqlConnection cn = new SqlConnection("context connection=true"))
{
cn.Open();
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = $"insert into t1(id,mc) values({id}, '{mc}')";
cmd.ExecuteNonQuery();
}
err = mc + id;
return 100;
// 在此处放置代码
}
可以返回记录集,示例见:https://blog.csdn.net/tjvictor/article/details/4731052
有两种方法:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void mypro3()
{
//返回 记录集
using (SqlConnection cn = new SqlConnection("context connection=true"))
{
cn.Open();
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = $"select * from t1";
SqlContext.Pipe.Send(cmd.ExecuteReader());
}
}
[Microsoft.SqlServer.Server.SqlProcedure]
public static void mypro4()
{
//返回DataSet内容
SqlDataRecord dataRecord = new SqlDataRecord(new SqlMetaData[] {
new SqlMetaData("Col1", SqlDbType.NVarChar,100),
new SqlMetaData("Col2", SqlDbType.Int)
});
//开始填充
SqlContext.Pipe.SendResultsStart(dataRecord);
for (int count = 0; count < 5; count++)
{
//SqlDataRecord.SetString类似DataRow的功能,像Table中填充值
dataRecord.SetString(0, count.ToString());
dataRecord.SetInt32(1, count);
//通过SendResultsRow把数据填充到Table,相关于Table.Rows.Add(DataRow);
SqlContext.Pipe.SendResultsRow(dataRecord);
}
//填充结束,返回结果集
SqlContext.Pipe.SendResultsEnd();
}
[Microsoft.SqlServer.Server.SqlProcedure]
public static void SPOne()
{
SqlPipe p;
SqlCommand sCmd = new SqlCommand();
sCmd.CommandText = "Select * from Person";
p = SqlContext.Pipe;
p.ExecuteAndSend(sCmd);
}
重新生成程序,并发布,即可写入数据库。
1. 发布时可能的问题:sqlserver版本不匹配(右键项目属性,选择目标数据库版本)
2. 发布时失败:..net framework版本不匹配,ms2008只支持.net2和.net3.5等版本(右键项目属性,选择.net frameork版为2)
发布成功后,在数据库中可查看到此存储过程。
在数据库中启用clr:
exec sp_configure 'clr enabled',1
reconfigure with override
上述存储过程的调用示例:
USE [test]
GO
DECLARE @return_value int,
@err nvarchar(max)
EXEC @return_value = [dbo].[mypro2]
@id = 844,
@mc = N'95k在', --前面不加N测试也正确
@err = @err OUTPUT
SELECT @err as N'@err' --前面不加N测试也正确
SELECT 'Return Value' = @return_value
GO
发布和部署:
在vs2017中直接点“发布”,连接到mssql后,在mssql中生成相应存储过程,完成部署过程。
或:
在vs2017中点“发布”时,选择生成脚本,最后生成sql文件,在mssql的管理器中打开脚本文件,打开“查询”菜单,选择“sqlcmd”模式,运行以上文件即可生成相应存储过程。在脚本中,c#装配件被转换成了16进制字符串形式保存。
在生成的sql脚本中,有数据库文件路径,这个经测试,不重要,路径随便更改一下也可运行成功。如下:
:setvar DatabaseName "test"
:setvar DefaultFilePrefix "test"
:setvar DefaultDataPath "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\"
:setvar DefaultLogPath "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\"
另外部署说明:
vs连接mssql时直接发布,可以生成相关存储集和存储过程,后续更新时可以生成sql脚本执行,但第一次无法使用脚本执行生成存储过程,提示装配件不存在,经查看在“C:\Users\ljq\AppData\Local\Microsoft\VisualStudio\SSDT\托管存储过程测试”目前下生成了mdf和ldf两个文件。
部署可以使用dll文件,参考:https://www.cnblogs.com/Brambling/p/8016060.html
CREATE ASSEMBLY MyFirstUdp FROM 'C:\Programming\MyFirstUdp.dll'; CREATE PROCEDURE HelloWorld AS EXTERNAL NAME MyFirstUdp.StoredProcedures.HelloWorld; EXEC HelloWorld;