繁体   English   中英

在.NET中将多个非SELECT MySQL语句作为单个命令文本执行

[英]Executing Multiple Non-SELECT MySQL Statements as a Single Command Text in .NET

我一直在从一个线程跳到另一个线程,但似乎找不到我需要的答案。

我想使用.NET在单个ExecuteNonQuery函数中执行非SELECT MySQL语句。

这是我要运行的一组SQL语句示例:

DROP procedure IF EXISTS `SubProcA`;
DROP procedure IF EXISTS `SubProcB`;
DROP procedure IF EXISTS `SubProcC`;


CREATE PROCEDURE 'SubProcD'()
BEGIN
SELECT
     (<Subselect Statement>) AS A
     ,(<Subselect Statement>) AS B
     ,(<Subselect Statement>) AS C;
END;


CREATE PROCEDURE 'SubProcE'(
     VarA TEXT,
     VarB VARCHAR(255),
     VarC VARCHAR(255),
     VarD tinyint(1)
)
BEGIN
     SET @Query = "";
     SET @Query = <Select Statement>;              
     PREPARE Statement FROM @Query;
     EXECUTE Statement;
     DEALLOCATE PREPARE Statement; 
END;

如您所见,其中有五个语句(3个DROP和2个CREATE)。 我在.NET中所做的是:

    CommandText = <The SQL Statement above stored in a String variable>
    Connection.Open()
    Command.CommandType = CommandType.Text
    Command.ExecuteNonQuery()
    Connection.Close()

假设sql语句没有任何语法错误,则在运行代码时仍然会出现错误。

我尝试砍掉(运行一个语句)的sql语句,并且将其推送通过。

我是否应该在其中放置一些特殊字符?

这些多个串联的查询在.net中被称为batch

您必须告诉MySQL连接器(MySQL的.net驱动程序)要在连接字符串中使用批处理。 使用AllowBatch选项

像这样:

var connectionString = Server=host;Database=db;Uid=user;Pwd=pass;AllowBatch=True;

您不能在批处理中包括存储过程调用。 它们必须与...CommandType=CommandType.StoredProcedure一起站立。

但是,这可能不起作用,具体取决于服务器和连接器的版本。 如果不只是使用“切掉” SQL语句的解决方法。 它工作正常,不会以可怕的方式破坏性能。

所以我设法找到一种方法来使这项工作:

  • 我使用MySQLClient而不是ODBC。
  • 在连接字符串中,包括allowbatch=true;allowuservariables=true;
  • 删除Delimiter $$Delimiter //及其尾部( $$//位于END
  • 只需将所有内容放入字符串变量中,然后执行即可。 只要确保您的sql语法正确即可。

这是我使用的测试代码:

Try
    Dim CONN = New MySql.Data.MySqlClient.MySqlConnection("server=localhost;user=<user>;database=<database>;port=3306;password=<password>;allowbatch=true;allowuservariables=true;")
    Dim CMDTXT =
        <sql>
            DROP procedure IF EXISTS `sample`; 
            CREATE PROCEDURE `sample`( 
                in_varA int(11),
                in_varB int(11),
                in_varC int(11)
            )
            BEGIN
                SET @query = CONCAT("SELECT ",in_varA + in_varB + in_varC);

                PREPARE Statement FROM @Query;
                EXECUTE Statement;
                DEALLOCATE PREPARE Statement;                        
            END;
        </sql>
            CONN.Open()
    Using TRAN = CONN.BeginTransaction
    Using CMD = CONN.CreateCommand
            CMD.CommandText = CMDTXT.Value
            CMD.CommandType = CommandType.Text
            CMD.ExecuteNonQuery()
            TRAN.Commit()
        End Using
End Using
    CONN.Close()
Catch ex As Exception
    MsgBox(ex.Message)
    Exit Sub
End Try
MsgBox("success")

我基本上使用这种样式来更新远程独立服务器。 我将复制对表,子proc等进行的所有更改的更新脚本。将它们放入一个sql文件中,将其在线存储(我使用Dropbox API),然后让我的应用程序(在客户端上)下载并应用在自己的本地数据库上所做的更改。

SET @query = CONCAT("SELECT ",in_varA + in_varB + in_varC);
PREPARE Statement FROM @Query;
EXECUTE Statement;
DEALLOCATE PREPARE Statement;      

我需要allowuservariables=true; 因此我可以在查询中声明@query和其他变量。 我在上面使用的代码段允许我创建动态子过程-根据需求建立一个自己的查询。

我希望这会帮助其他人。

特别感谢O. Jones。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM