Python 确定sql语句是否以单词SELECT开头

Python 确定sql语句是否以单词SELECT开头,python,mysql,sql,regex,Python,Mysql,Sql,Regex,我正在尝试对输入SQL字符串进行一些基本验证。我想确保查询的第一个单词是SELECT,否则我会出错。以下是一些例子: 1) yes SELECT * FROM table 2) no # SELECT * FROM table; DROP TABLE table; 3) no /* SELECT * FROM TABLE */ DROP TABLE table; 4) yes # here is a comment SELECT * FROM table 5) yes /*

我正在尝试对输入SQL字符串进行一些基本验证。我想确保查询的第一个单词是
SELECT
,否则我会出错。以下是一些例子:

1) yes
SELECT * FROM table

2) no
# SELECT * FROM table;
DROP TABLE table;

3) no
   /* SELECT * FROM 
   TABLE */ DROP TABLE table;

4) yes
# here is a comment
SELECT * FROM table

5) yes
/* here is a
comment */ SELECT * FROM table

以及各种其他的。也许这更像是一个正则表达式解决方案或string.replace。但是,有什么好方法可以查看是否输入了SQL SELECT语句呢?

我会使用适当的工具来执行该作业,获取第一个语句对象并检查它是否属于
SELECT
类型:

In [1]: import sqlparse

In [2]: queries = [
   ...:     "SELECT * FROM table",
   ...:     """
   ...:     # SELECT * FROM table;
   ...:     DROP TABLE table;
   ...:     """,
   ...:     """/* SELECT * FROM 
   ...:    TABLE /* DROP table table;""",
   ...:    """
   ...:    # here is a comment
   ...:    SELECT * FROM table
   ...:    """
   ...: ]

In [3]: def is_select(query):
             first_statement = next((token for token in sqlparse.parse(query) if isinstance(token, sqlparse.sql.Statement)), None) 
             if first_statement:
                 return first_statement.get_type() == 'SELECT'

In [4]: for query in queries:
    ...:     print(query, is_select(query))

    SELECT * FROM table 
    True

    # SELECT * FROM table;
    DROP TABLE table;
    False

   /* SELECT * FROM 
   TABLE /* DROP table table; 
   False

   # here is a comment
   SELECT * FROM table
   True

尽管可以使用正则表达式和其他基于文本的技巧,但一个合适的SQL解析器(如SQL解析器)是可行的。例如:

import sqlparse
statements = sqlparse.parse(my_evil_sql)
for statement in statements:
  if statement.get_type() != "SELECT":
    raise Exception("Non-select statement encountered!")

请注意,
get_type()
忽略语句开头的空格和注释。

也许是一个更安全的解决方案,或者除此之外的其他方法是重新授予用于连接数据库的数据库用户的访问权限,以便只允许选择。
sql.lower().startswith(“选择”)
?@Selcuk是的,但这是不正确的。如果第一行是评论呢?我看不出这是如何防止任何事情发生的。SQL是否仍然支持删除同一字符串中的SELECT之后的所有记录?@DavidL是的,这就是我没有将其作为答案发布的原因。我过于简单化了。一个合适的SQL解析器,比如,就是最好的选择。谢谢。在所有语句或仅在第一个语句中检查有什么区别吗?@DavidL为了安全起见,您可能会检查所有语句。更重要的是,如果启用了db驱动程序,则在每次执行时禁用多个查询。谢谢