代码之家  ›  专栏  ›  技术社区  ›  Ben Butterworth

cursor.execute(“[some sql query]”,t)导致语法错误[duplicate]

  •  0
  • Ben Butterworth  · 技术社区  · 6 年前

    问题:是否可以使用变量作为表名,而不必使用字符串构造函数?


    信息:

    我正在做一个项目,从我的一个恒星模拟编目数据。为此,我将所有数据加载到sqlite数据库中。它工作得很好,但是我决定给我的数据库增加更多的灵活性、效率和可用性。我计划稍后在模拟中添加小行星,并希望为每个恒星创建一个表。这样我就不必为每个太阳系1-4公里的距离查询20米的行星表了。

    目前我正在做的是:

    cursor.execute("CREATE TABLE StarFrame"+self.name+" (etc etc)")
    

    cursor.execute("CREATE TABLE StarFrame(?) (etc etc)",self.name)
    

    尽管我知道这可能是不可能的。尽管我会满足于

    cursor.execute("CREATE TABLE (?) (etc etc)",self.name)
    

    如果这是不可能的,我会接受这个答案,但如果有人知道如何做到这一点,一定要告诉。:)

    我在用python编写代码。

    0 回复  |  直到 7 年前
        1
  •  40
  •   Donald Miner    14 年前

    不幸的是,表不能作为参数替换的目标(我没有找到任何确定的源代码,但是我在一些web论坛上看到过)。

    )(][;, 还有空白。基本上,保持 A-Z a-z 0-9

    def scrub(table_name):
        return ''.join( chr for chr in table_name if chr.isalnum() )
    
    scrub('); drop tables --')  # returns 'droptables'
    
        2
  •  9
  •   Ned Batchelder    14 年前

    我不会把数据分成多个表。如果在星型列上创建索引,那么高效地访问数据就不会有任何问题。

        3
  •  4
  •   jubibanna    6 年前

    对于那些想把表作为变量的人,我是从对同一个问题的另一个答复中得到的 here :

    上面说了下面的话,就行了。都是引自 :

    query = 'SELECT * FROM {}'.format(table)
    c.execute(query)
    

    需要注意的一点是表名的值的来源。如果来自不受信任的源(例如用户),则需要验证表名以避免潜在的SQL注入攻击。一种方法可能是构造一个参数化查询,从数据库目录中查找表名:

    import sqlite3
    
    def exists_table(db, name):
        query = "SELECT 1 FROM sqlite_master WHERE type='table' and name = ?"
        return db.execute(query, (name,)).fetchone() is not None
    
        4
  •  1
  •   Windows Eight    6 年前

    尝试使用字符串格式:

    sql_cmd = '''CREATE TABLE {}(id, column1, column2, column2)'''.format(
                'table_name')
    db.execute(sql_cmd)
    

    替换 'table_name'

        5
  •  0
  •   Davin Edison    5 年前

    你可以用这样的东西 conn = sqlite3.connect() createTable = '''CREATE TABLE %s (# );''' %dateNow) conn.execute(createTable)

    基本上,如果我们想根据现在的日期将数据分成几个表,例如,您想基于日期监视系统。

    createTable=''创建表%s(35;);''%dateNow)意味着您创建了一个带有变量dateNow的表,根据您的编码语言,您可以将dateNow定义为一个变量,以便从您的编码语言中检索当前日期。

        6
  •  -1
  •   Rolf of Saxony    7 年前

    正如在其他答案中所说,“表不能作为参数替换的目标”,但是如果您发现自己处于一个没有选择的绑定中,这里有一种测试提供的表名是否有效的方法。
    注:我把这张桌子命名为一只真正的猪,试图覆盖所有的底座。

    import sys
    import sqlite3
    def delim(s):
      delims="\"'`"
      use_delim = []
      for d in delims:
       if d not in s:
        use_delim.append(d)
      return use_delim
    
    db_name = "some.db"
    db = sqlite3.connect(db_name)
    mycursor = db.cursor()
    table = 'so""m ][ `etable'
    delimiters = delim(table)
    if len(delimiters) < 1:
        print "The name of the database will not allow this!"
        sys.exit()
    use_delimiter = delimiters[0]
    print "Using delimiter ", use_delimiter
    mycursor.execute('SELECT name FROM sqlite_master where (name = ?)', [table])
    row = mycursor.fetchall()
    valid_table = False
    if row:
        print (table,"table name verified")
        valid_table = True
    else:
        print (table,"Table name not in database", db_name)
    
    if valid_table:
        try:
            mycursor.execute('insert into ' +use_delimiter+ table +use_delimiter+ ' (my_data,my_column_name) values (?,?) ',(1,"Name"));
            db.commit()
        except Exception as e:
            print "Error:", str(e)
        try:
            mycursor.execute('UPDATE ' +use_delimiter+ table +use_delimiter+ ' set my_column_name = ? where my_data = ?', ["ReNamed",1])
            db.commit()
        except Exception as e:
            print "Error:", str(e)
    db.close()
    
        7
  •  -3
  •   act123    8 年前

    可以将字符串作为SQL命令传递:

    import sqlite3
    conn = sqlite3.connect('db.db')
    c = conn.cursor()
    tablename, field_data = 'some_table','some_data'
    query = 'SELECT * FROM '+tablename+' WHERE column1=\"'+field_data+"\""
    c.execute(query)
    
    推荐文章