【问题标题】:Determine if a SQL query alters the database structure确定 SQL 查询是否改变了数据库结构
【发布时间】:2011-12-07 20:04:28
【问题描述】:

我试图找出一个字符串是否包含某些通过以下方式改变数据库的 SQL 命令:

  • 创建新表
  • 删除现有表
  • 创建新的表列
  • 删除现有表列

现在我正在 strpos 搜索 ALTERCREATEDROP,应该可以。

是否还有其他命令可以执行上述操作并且我应该将其包含在我的搜索中?

请注意,出于安全原因,我不需要这个。我只需要知道表架构是否更改,这样我就可以更新架构信息的本地缓存...

【问题讨论】:

  • 更好的方法是不允许用户执行此类操作,只有管理员才能创建或更改或删除表,并且任何用户都不应拥有权限。
  • srsly 为什么要 +1 上面的评论?我刚刚写道,这不是出于安全原因:)
  • 我们怎么知道这不是一个管理界面?很多软件都有一个管理界面,允许人们更改表格。通常这些是用户定义的表,核心应用表是不允许的,但这是合法的设计。
  • 您的应用程序本身是否旨在允许用户修改架构?他们是通过一些 UI 来做到这一点,还是用户可以实际输入他们希望运行的 SQL?
  • @david:你说得对:(我想我会每天让缓存过期一次或其他什么......

标签: php sql string strpos


【解决方案1】:

对于某些 DBMS(PostgreSQL、MS SQL Server、Informix)SELECT ... INTO ... 可以创建新表。

【讨论】:

  • 在MYSQL中,也有RENAME(数据库或表)。
【解决方案2】:

这将很难通过字符串检查来实现。

还有其他方法可以进行更改,例如:

SELECT *
INTO SomeTable
FROM SomeOtherTable

sp_rename 'OldTable' 'NewTable'

安全或 DDL 触发器可能是更好的选择。

【讨论】:

    【解决方案3】:

    如果在字符串常量中出现 ALTER、CREATE 或 DROP,则可能会出现误报。

    INSERT INTO News (headline) VALUES ('Stocks DROP for no reason!');
    

    另外strpos() 只查找字面子字符串,它不知道子字符串是否是较长单词的一部分。

    SELECT * FROM CLOTHING_ALTERATIONS
    

    因此您可能希望使用正则表达式并确保单词位于语句的开头,并且是一个完整的单词。

    $num_matches = preg_match("/^\s*(ALTER|CREATE|DROP|RENAME)\b/m", $sql);
    

    如果字符串包含 SQL 行注释,则使用多行正则表达式匹配很重要。

    -- the following statement is run in my add_column() function
    ALTER TABLE mytable ADD COLUMN ...
    

    它可能更复杂,因为许多 SQL 实现允许 /* */ 作为内联 comments 的分隔符。

    /* added 12/7/2011 */ CREATE /* TEMPORARY */ TABLE mytable ...
    

    【讨论】:

      猜你喜欢
      • 2019-07-09
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多