【问题标题】:MySQL - How to test user variable and use it in DROP VIEWMySQL - 如何测试用户变量并在 DROP VIEW 中使用它
【发布时间】:2019-03-11 11:46:16
【问题描述】:

我是 MySQL 中用户变量的新手,在尝试将它们用于除 SELECT 语句之外的任何内容时遇到了一些错误。我正在尝试运行批处理作业来删除在我的数据库中创建的临时视图。流程是:

第 1 步:识别临时视图并将列表放入变量中。

第二步:测试变量是否为空

第 3 步:删除视图

问题 1:drop 不起作用,即使我不测试 null。我收到此消息:第 13 行的 ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“@VIEWLIST_PRE”附近使用正确的语法

问题 2:包含 null 测试时不起作用。我收到此错误:mysql:[警告] 在命令行界面上使用密码可能不安全。 第 12 行的 ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'IF(@VIEWLIST_PRE IS NULL) THEN 附近使用的正确语法 DROP VIEW @VIEWLIST_PRE' 在第 1 行

下面是代码。这必须如何编写才能工作?我真的很感激帮助!谢谢!!

SET SESSION group_concat_max_len = 18446744073709551615;

-- Get the PreSummary views
SET @VIEWLIST_PRE = (SELECT
                    CONCAT(
                        GROUP_CONCAT(TABLE_NAME)
                    ) AS stmt
                    FROM information_schema.TABLES
                    WHERE TABLE_SCHEMA = "raptor" AND TABLE_NAME LIKE "%Pre%");

SELECT @VIEWLIST_PRE; -- THIS WORKS!
IF(@VIEWLIST_PRE IS NULL) THEN  -- BREAKS
    DROP VIEW @VIEWLIST_PRE;  -- BREAKS
END IF;

* 解决方案 *

我调整了 Used_By_Already 的解决方案(据我所知,在准备好的语句中一次只能执行 one command)。这是批量 DROP 的最终代码:

SET @VIEWLIST_PRE = (SELECT
                    CONCAT(
                        GROUP_CONCAT(TABLE_NAME)
                    ) AS stmt
                    FROM information_schema.TABLES
                    WHERE TABLE_SCHEMA = "raptor" AND TABLE_NAME LIKE "%Pre%");
SET @DROP_VIEW_PRE = CONCAT('DROP VIEW IF EXISTS ', @VIEWLIST_PRE);
PREPARE stmt1 FROM @DROP_VIEW_PRE;
EXECUTE stmt1;

提出了一个很好的问题,即为什么不使用定向投放。原因是它没有从 PHP 成功执行,但没有收到错误。但是,经过大量搜索,我发现了问题,现在可以进行有针对性的下降。

【问题讨论】:

  • 我看到聚合方法 GROUP_CONCAT() 但没有 GROUP BY 子句,你确定 GROUP_CONCAT() 有感觉?
  • 为什么要创建“临时视图”?似乎是一件很奇怪的事情。此外,您需要形成“动态 sql”以使用变量 as SQL.
  • 该代码用于收集视图列表(我从另一个堆栈溢出帖子中获取)。在为报告创建数据透视表时,视图是由单独的代码生成的,而不是发布的。 :-)

标签: mysql variables null prepared-statement group-concat


【解决方案1】:

我不确定您为什么或如何创建这些临时视图,但与其尝试定期进行批量清理,不如直接使用:

drop view IF EXISTS some_view_name;

就在您当前用于创建每个临时视图的代码之前。

这样,视图是否存在都无关紧要。


如果您要继续进行看起来像批量清理的操作,那么查询需要看起来更像这样:

SET @VIEWLIST_PRE = (concat((select group_concat(concat('drop view if exists ',table_name) SEPARATOR '; ')  
                             from information_schema.views 
                             where table_schema = 'raptor' and table_name  like'%Pre%')
                            ,';'))

那么生成的字符串应该是这样的:

drop view if exists Pre1; drop view if exists Pre2;

然后您需要使用prepared statement 来执行生成的SQL。您不能只将用户变量作为 SQL 代码字符串包含在查询中。

见:MySQL Prepared Sattement Syntax

【讨论】:

  • 谢谢!我会试试的。
  • Used_By_Already - 通过稍微调整您的解决方案(我将在上面发布),我能够让批量删除工作。详细说明我使用批量删除而不是目标删除(这会更干净)的原因:a)通过执行 MySQL 表单 PHP 生成视图。 b)下降不适用于 PHP,但我也没有收到错误代码。当我将命令的回显从 PHP 复制/粘贴到 MySQL Workbench 时,代码在 MySQL 中完美执行。因此,我无法找到问题所在。因此,批量删除是一种技巧,但我可以开始工作。
  • 另一个考虑因素 - 我如何测试空/空用户变量?如果没有什么可丢弃的,我不想执行命令。再次感谢 - 我很感激!
【解决方案2】:

我调整了 Used_By_Already 的解决方案(据我所知,在准备好的语句中一次只能执行 one command)。这是批量 DROP 的最终代码:

SET @VIEWLIST_PRE = (SELECT
                    CONCAT(
                        GROUP_CONCAT(TABLE_NAME)
                    ) AS stmt
                    FROM information_schema.TABLES
                    WHERE TABLE_SCHEMA = "raptor" AND TABLE_NAME LIKE "%Pre%");
SET @DROP_VIEW_PRE = CONCAT('DROP VIEW IF EXISTS ', @VIEWLIST_PRE);
PREPARE stmt1 FROM @DROP_VIEW_PRE;
EXECUTE stmt1;

提出了一个很好的问题,即为什么不使用定向投放。原因是它没有从 PHP 成功执行,但没有收到错误。但是,经过大量搜索,我发现了问题,现在可以进行有针对性的下降。

【讨论】:

    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 2012-03-04
    • 2011-07-28
    • 1970-01-01
    相关资源
    最近更新 更多