验证MySql查询

时间:2009-07-27 18:00:13

标签: mysql

如何在执行之前验证MySql查询?

5 个答案:

答案 0 :(得分:7)

没有好办法!基本上,您需要执行该语句;没有-l标志。

两种常用方法是:

  1. 使用EXPLAIN前面的SELECT。这仅适用于SELECT语句,因此它不是一般解决方案
  2. 使用交易。这只适用于5.x Innodb表,因此它不是一般解决方案。对于您不想花时间执行的SELECTS,这也没有用。
  3. 这些都不适合我。我发现唯一不错的通用解决方案是创建一个测试套件,以真实的方式创建临时表,然后对它们执行查询:

    CREATE TEMPORARY TABLE users_test LIKE users;
    CREATE TEMPORARY TABLE auth_test LIKE auth;
    

    您实际上可以忘记制作这些临时工并将它们保存在'_test'数据库中,并在适当的时候更改您的DSN。

    否则,您需要对查询进行参数化,以便在必要时告诉它使用'_test'表。

    这远非理想,但它是我发现的最佳解决方案,因为它快速执行查询(没有数据加入/决定)并且不会影响数据库。

    如果有人证明我错了,并且指向接受字符串并返回TRUE或错误消息的MySQL Parser,我会很高兴。

答案 1 :(得分:2)

我想我已经找到了办法。您可以运行PREPARE并创建一个声明。

我猜在伪代码中我会做这样的事情:

foreach list_of_queries as query
  try
    MySQL_API::run('PREPARE validate_sql FROM ' + quote(query))
  catch MySQL::Error as e
    print 'Query ' + query + ' has errors'
    print e.errno + ' -> ' + e.error
  finally
    MySQL_API::run('DEALLOCATE PREPARE validate_sql')
  end   
end

示例


 CREATE TABLE `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` text,
  `doc_id` int(11) DEFAULT '1',
  `date_inserted` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

-- DELETE
mysql> PREPARE validate_sql FROM 
'DELETE FROM `comments` WHERE gid = ?';
ERROR 1054 (42S22): Unknown column 'gid' in 'where clause'

-- SELECT
mysql> PREPARE validate_sql FROM 
'SELECT doc_id, content, date_modified FROM `comments` WHERE id = ?';
ERROR 1054 (42S22): Unknown column 'date_modified' in 'field list'

-- INSERT
mysql> PREPARE validate_sql FROM 
'INSERT INTO comments VALUES(?,?,?)';
ERROR 1136 (21S01): Column count doesn't match value count at row 1
mysql> PREPARE validate_sql FROM 
'INSERT INTO comments(id, contents, doc_id) VALUES(?,?,?)';
ERROR 1054 (42S22): Unknown column 'contents' in 'field list'

-- ALTER TABLE
mysql> PREPARE validate_sql FROM 
'ALTER TABLE `comments` ADD COLUMN `my_col` bint UNSIGNED 
NOT NULL DEFAULT "0" AFTER `content`';
ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 
'bint unsigned not null default "0" after `content`' at line 1
-- Unfortunately for ALTER TABLE statements 
-- you do not get more specific syntax errors
-- such as "Wrong/missing field type"

答案 2 :(得分:1)

您还可以在事务中包含查询,然后取消事务。通过这种方式,您还可以查看查询结果(即使它是更新或删除查询),然后相应地执行操作,而不会影响数据库(除非您提交事务)。

答案 3 :(得分:0)

运行EXPLAIN SELECT …

它将解析您的查询并向您显示执行计划(它将用于执行查询的算法以及顺序)。

这本身就是一件好事,我。即总是这样做,不仅仅是为了验证。

这将帮助您了解窗帘背后发生的事情并构建更有效的查询。

答案 4 :(得分:0)

添加带有“blackhole”的从站作为默认表类型。

现在对该奴隶运行任何查询。