首页 > sqlserver可以实现在表中插入一行后对外发送socket通信吗?

sqlserver可以实现在表中插入一行后对外发送socket通信吗?

我在表中添加了after insert触发器,并在触发器中调用了c#编译的.dll,但是一执行insert操作,就报如下错误

消息 6522,级别 16,状态 1,过程 TestSql,第 1 行
在执行用户定义例程或聚合 "TestSql" 期间出现 .NET Framework 错误: 
System.Security.HostProtectionException: 试图执行 CLR 主机禁止的操作。

受保护的资源(只有完全信任才可访问)是: All
要求的资源是: UI

System.Security.HostProtectionException: 
   在 CLRTriggers.Test()
。

我不懂sqlserver和c#(由于c#语法和java的相似性,所以这里基本靠猜……),上网了搜索了一下仍然搞不懂这是什么意思。

在sqlserver中添加.dll如下(叫做clr?)

Create ASSEMBLY Test
FROM 'd:\test.dll'
WITH PERMISSION_SET = SAFE;

在表中添加触发器如下,

CREATE TRIGGER TestSql
on Table_2
AFTER INSERT
AS
EXTERNAL NAME Test.CLRTriggers.Test

.dll源码如下(一半是抄的官网例子…………),

public class CLRTriggers
{
    [SqlTrigger(Name = @"Test", Target = "[dbo].[Table_1]", Event = "AFTER INSERT")]
    public static void Test()
    {
        string index;
        string name;
        string time;
        SqlCommand command;
        SqlTriggerContext triggContext = SqlContext.TriggerContext;
        SqlPipe pipe = SqlContext.Pipe;
        SqlDataReader reader;

        switch (triggContext.TriggerAction)
        {
            case TriggerAction.Insert:

                using (SqlConnection connection
                   = new SqlConnection(@"context connection=true"))
                {
                    connection.Open();
                    command = new SqlCommand(@"SELECT * FROM INSERTED;",
                       connection);
                    reader = command.ExecuteReader();
                    reader.Read();
                    index = Convert.ToString(reader[0]);
                    name = (string)reader[1];
                    time = (string)reader[2];
                    reader.Close();
                    string message = "{" + "index:" + index + ",name:" + name + ",time:" + time + "}";

                    int port = 6385;
                    IPAddress ip = IPAddress.Parse("127.0.0.1");
                    IPEndPoint ipEnd = new IPEndPoint(ip, port);
                    string pwd = "123456";

                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    try
                    {
                        client.Connect(ipEnd);
                        byte[] byteContent = Encoding.GetEncoding("GBK").GetBytes(pwd);
                        client.Send(byteContent, byteContent.Length, SocketFlags.None);

                        string recv = "";
                        byte[] buffer = new byte[1024];
                        int num = client.Receive(buffer, buffer.Length, SocketFlags.None);
                        recv += Encoding.GetEncoding("GBK").GetString(buffer, 0, num);
                        if (recv.Equals("ok"))
                        {
                            byteContent = Encoding.GetEncoding("GBK").GetBytes(message);
                            client.Send(byteContent, byteContent.Length, SocketFlags.None);
                            client.Close();
                        }
                        else
                        {
                            client.Close();
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }

                }
                break;
        }
    }
}

看那个错误信息,应该是SQLServer不信任插入进去的.net程序,所以对类库做了一些限制。你可以根据这个去搜一下,看看有没有什么结果。

通常来讲,为什么不要去解决这个问题,因为首先这严重拖慢了SQLServer,其次更加严重的,开了个大漏洞给对手使用。

【热门文章】
【热门文章】