• Sql语句不能识别Go的解决办法(动态创建表的触发器)


    问题来源

    用sqlserver直接打开sql文本,执行没问题,但是当用Sqlcommand类执行cmdtext命令文本时总是失败报错。

    原因分析及解决

    用数据库直接执行sql语句没问题,甚至还可以用Go来进行分批处理,但是当你用链接类访问数据库,并执行sql语句时就有些限制,如下:

    System.Data.SqlClient.SqlCommand cmd;
    try
    {
         using (System.Data.SqlClient.SqlConnection newconn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=Rfa_LPP3;Integrated Security=True"))
       {
          cmd = new System.Data.SqlClient.SqlCommand("Create trigger triggerName  on  dbo.tableName    for insert    as     begin    declare @ID int;    select @ID=ID from inserted;   print @ID   end", conn);
          cmd.ExecuteNonQuery();
          cmd.Dispose();
       }
    }
    cath(Exception ex)
    {
       throw;//会抛出异常
    }

    会“go附近有语法错误”“'CREATE TRIGGER' 必须是查询批次中的第一个语句”等错误

    首先来看下GO的用法:

    SQL Server 实用工具将 GO 解释为应将当前的 Transact-SQL 批处理语句发送给 SQL Server 的信号。SQL Server 应用程序可将多条 Transact-SQL 语句作为一个批处理发给 SQL Server 去执行。在此批处理中的语句编译成一个执行计划。程序员在 SQL Server 实用工具中执行特定语句,或生成 Transact-SQL 语句脚本在 SQL Server 实用工具中运行,用 GO 来标识批处理的结束

    注意:1.GO 命令和Transact-SQL 语句不可在同一行上。但在 GO 命令行中可包含注释。2.CREATE DEFAULT、CREATE PROCEDURE、CREATE RULE、CREATE TRIGGER 和 CREATE VIEW 语句不能在批处理中与其它语句组合使用。批处理必须以 CREATE 语句开始。所有跟在该批处理后的其它语句将被解释为第一个 CREATE 语句定义的一部分

     

    再来看看SqlCommand类的解释:表示要对 SQL Server 数据库执行的一个 Transact-SQL 语句或存储过程。所以用SqlCommand去执行的文本内容可以是多条sql语句,或者是一个存储过程,或者触发器创建等,但是不能与触发器创建等组合使用,且不能使用Go批结束命令。

     

    但是,我又想在一个mySql.sql文本中一起执行,该怎么办呢?

    提供三种思路:

    1.将创建触发器的sql当字符串放到变量里面,然后exec执行变量。

    2.将创建触发器的sql放在存储过程,然后exec存储过程执行。

    3.将创建触发器的sql单独执行一次。每个创建的sql单独取出来执行。


    最后贴上代码.
    1.方法1可执行的sql
    USE [LPP12]  
    declare @sql nvarchar(max);
    set @sql='Create trigger triggerName  on  dbo.tableName    for insert    as     begin    declare @ID int;    select @ID=ID from inserted;   print @ID   end';
    exec(@sql);

    2.方法2的sql

    create procedure proc_name
    as
    begin
    declare @sql nvarchar(max);
    set @sql='Create trigger triggerName  on  dbo.tableName    for insert    as     begin    declare @ID int;    select @ID=ID from inserted;   print @ID   end';
    exec(@sql); 
    end

    3.方法3:将sql存放在xml里面,每次取出执行一次。

    //xml内容
    <?xml version="1.0" encoding="utf-8" ?>
    <TR>
      <add name="trigger_insert" value="trigger_familyContent_insert" 
        value="Create trigger trigger_name
    on dbo.tablename
    for insert
    as 
    begin
    declare @ID int;
    select @ID=ID from inserted; 
    end"></add>
      <add 
        name="trigger_insert" 
        value="Create trigger trigger_name
    on dbo.tablename
    for insert
    as 
    begin
    declare @ID int;
    select @ID=ID from inserted; 
    end"></add>
      
    </TR> 
    //c#代码
     System.Data.SqlClient.SqlCommand cmdnew;
                            try
                            {
                                string _XmlPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"SqlCreateTrggers.xml";
                                XmlDocument doc = new XmlDocument();
                                doc.Load(_XmlPath);
                                XmlNodeList nodes = doc.SelectSingleNode("TR").ChildNodes;
                                
                                using (System.Data.SqlClient.SqlConnection newconn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=Rfa_LPP3;Integrated Security=True"))
                                {
                                    newconn.Open();
                                    cmdnew = new System.Data.SqlClient.SqlCommand();
                                    foreach (XmlElement node in nodes)
                                    {
                                        string value = node.Attributes["value"].Value;
                                        cmdnew = new System.Data.SqlClient.SqlCommand(value.Replace("
    ", "  ").Replace("
    ", "  ").Replace("	", "  "), newconn);
                                        int count = cmdnew.ExecuteNonQuery();
                                    }
                                    cmdnew.Dispose();
                                    newconn.Close();
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                                Console.ReadKey();
                            }

    有错欢迎指正。

  • 相关阅读:
    Go语言的性能测试对比
    学习笔记
    使用TCPDump分析Redis的Pipeline比Multi更快的原因
    基于Redis/Memcached的高并发秒杀设计
    这些 .Net and Core 相关的开源项目,你都知道吗?(持续更新中...)
    《.Net 的冰与火之歌》寄雁传书,你必须知道的C#参数知识大盘点
    分享自己的超轻量级高性能ORM数据访问框架Deft
    Expression2Sql的一些语法更新
    介绍一个可以将Expression表达式树解析成Transact-SQL的项目Expression2Sql
    记一次随机字符串生成算法的随机概率与性能的提升
  • 原文地址:https://www.cnblogs.com/lipanpan/p/3851698.html
Copyright © 2020-2023  润新知