在.net中作为单个命令文本执行多个非select mysql语句

zu0ti5jz  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(322)

我一直在从一条线跳到另一条线,但似乎找不到我需要的答案。
我想使用.net在单个executenonquery函数中执行非select mysql语句。
下面是我想要运行的一组sql语句示例:

  1. DROP procedure IF EXISTS `SubProcA`;
  2. DROP procedure IF EXISTS `SubProcB`;
  3. DROP procedure IF EXISTS `SubProcC`;
  4. CREATE PROCEDURE 'SubProcD'()
  5. BEGIN
  6. SELECT
  7. (<Subselect Statement>) AS A
  8. ,(<Subselect Statement>) AS B
  9. ,(<Subselect Statement>) AS C;
  10. END;
  11. CREATE PROCEDURE 'SubProcE'(
  12. VarA TEXT,
  13. VarB VARCHAR(255),
  14. VarC VARCHAR(255),
  15. VarD tinyint(1)
  16. )
  17. BEGIN
  18. SET @Query = "";
  19. SET @Query = <Select Statement>;
  20. PREPARE Statement FROM @Query;
  21. EXECUTE Statement;
  22. DEALLOCATE PREPARE Statement;
  23. END;

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

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

假设sql语句没有任何语法错误,在运行代码时仍然会出现错误。
我试着切碎(运行一条语句)的sql语句,然后它就成功了。
我是不是应该在里面放些特别的东西?

cfh9epnr

cfh9epnr1#

这些多个串联查询称为 batch 用.net的说法。
您必须告诉mysql连接器(mysql的.net驱动程序)您想在连接字符串中使用批处理。使用 AllowBatch 选项。
像这样:

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

不能在批处理中包含存储过程调用。他们必须单独面对 ...CommandType=CommandType.StoredProcedure .
但是,根据服务器和连接器的版本,这可能不起作用。如果它不只是使用你的变通方法“斩断”sql语句。它运行良好,不会以一种可怕的方式破坏性能。

amrnrhlw

amrnrhlw2#

所以我设法找到了一个方法来实现这一点:
我使用mysqlclient而不是odbc。
在连接字符串中,包括 allowbatch=true;allowuservariables=true; .
删除 Delimiter $$ 或者 Delimiter // 它的尾巴 $$ 或者 // 位于 END )
把所有的东西都放到一个字符串变量中,然后开火。只要确保你的sql语法是正确的。
这是我使用的测试代码:

  1. Try
  2. Dim CONN = New MySql.Data.MySqlClient.MySqlConnection("server=localhost;user=<user>;database=<database>;port=3306;password=<password>;allowbatch=true;allowuservariables=true;")
  3. Dim CMDTXT =
  4. <sql>
  5. DROP procedure IF EXISTS `sample`;
  6. CREATE PROCEDURE `sample`(
  7. in_varA int(11),
  8. in_varB int(11),
  9. in_varC int(11)
  10. )
  11. BEGIN
  12. SET @query = CONCAT("SELECT ",in_varA + in_varB + in_varC);
  13. PREPARE Statement FROM @Query;
  14. EXECUTE Statement;
  15. DEALLOCATE PREPARE Statement;
  16. END;
  17. </sql>
  18. CONN.Open()
  19. Using TRAN = CONN.BeginTransaction
  20. Using CMD = CONN.CreateCommand
  21. CMD.CommandText = CMDTXT.Value
  22. CMD.CommandType = CommandType.Text
  23. CMD.ExecuteNonQuery()
  24. TRAN.Commit()
  25. End Using
  26. End Using
  27. CONN.Close()
  28. Catch ex As Exception
  29. MsgBox(ex.Message)
  30. Exit Sub
  31. End Try
  32. MsgBox("success")

我基本上在更新远程独立服务器时使用了这种风格。我会复制我对表、子进程等所做的所有更改的更新脚本,将它们放入一个sql文件中,在线存储(我使用dropbox api),然后让我的应用程序(在客户端)下载它并将更改应用到自己的本地数据库中。

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

我需要那个 allowuservariables=true; 所以我可以宣布 @query 以及查询中的其他变量。我在上面使用的代码段允许我创建动态子脚本——根据需求构建自己的查询。
我希望这能帮助别人。
特别感谢o。琼斯。

展开查看全部

相关问题