gpt4 book ai didi

SQLITE 标识符的限制字符是什么

转载 作者:行者123 更新时间:2023-12-03 23:24:09 25 4
gpt4 key购买 nike

我正在尝试构建一个 SQL 参数自动绑定(bind)到新查询的系统。根据这个线程:

SQL Server - Invalid characters in parameter names

@、_ 和# 字符应允许在标识符中。所以我尝试将参数构建为:

:表名#字段名

但是当我这样做时会出现错误:

PBdatabase.select_query: [1] DB[2] prepare() SELECT * FROM creature WHERE pk = :creature#pk [near "#pk": syntax error]



似乎它不喜欢 # 字符,我尝试使用下划线,它似乎有效,但我已经在字段名称中使用了下划线。这就是为什么我想使用不同的角色。

由于上面的线程讨论了 SQL 服务器,因此 SQLITE 中的受限字符可能会有所不同。我找到了 SQLITE 受限关键字列表,但没有找到字符。

有人知道我可以使用哪个其他特殊字符吗?

更新

有人想知道我有什么用处。这是一个示例,假设您有 2 个具有 1 对 N 关系的表: Fleet 包含船只。

您想显示一个由 2 个 block 组成的表格,其中顶部显示 1 当时选择的舰队。底部区 block 列出了舰队中的所有船只。

第一个 block 查询将类似于:
SELECT pk, number, location  FROM fleet;

然后所选条目的字段将被放入具有以下名称的字段注册表中(假设 # 符号有效):
:fleet#pk
:fleet#number
:fleet#location

然后将运行第二个 block 的第二个查询,包括上面的注册字段。所以查询看起来像:
SELECT pk, fk_fleet, name  FROM ship WHERE fk_fleet = :fleet#pk

此查询使用上述查询中的参数。标识符将替换为上一个查询中的值。这允许仅显示与上面所选舰队链接的船只,而不是所有可用的船只。

现在你们中的一些人可能会说我可以简单地保存我想要的变量并将它们作为参数传递给下一个查询。问题是所有查询都是从数据库加载的。我实际上不知道要运行哪个查询以及需要为另一个查询保存哪个值。相反,我将它们全部保存在注册表中,如果另一个 SQL 语句要求提供参数,则该值将可用。

最佳答案

SQLite 和 SQL Server 相似,但它们的语法略有不同,就像 SQL 的所有实现通常有不同的规则一样。
SQLite 允许使用字母 A - Z , a - z , 0 - 9 , _ , $ , 冒号对 "::"在第一个字符之后,并且 Unicode 字符大于 u007f。
此外,在参数末尾,可以添加括号:() , 其间可以是除 ASCII 空白字符和 ) 之外的任何字符字符。 0x00也永远不允许(因为这表示 C 字符串的结尾)。
例子
所以以下参数是有效的::a , :_ , :$ , :a:: , :A , :9 , :😁 , :  (U+2000,Unicode en 四空格字符),:a(:/$asd() .
虽然这些是无效的::# , ::: , :: , :; , :( , :( ) (一个普通的 ASCII 空间)
来源
我在 SQLite 网站上找到了一篇文章(参见 https://www.sqlite.org/draft/tokenreq.html),其中指定命名参数(也称为变量)可以包括:

A "parameter name" is defined to be a sequence of one or morecharacters that consists of ALPHANUMERIC characters and/ordollar-signs (u0025) intermixed with pairs of colons (u003a) andoptionally followed by any sequence of non-zero, non-WHITESPACEcharacters enclosed in parentheses (u0028 and u0029).


其中 ALPHANUMERIC 字符定义为:

ALPHABETICAny of the characters in the range u0041 through u005a (letters "A" through "Z")or in the range u0061 through u007a (letters "a" through "z") or the characteru005f ("_") or any other character larger than u007f.



NUMERICAny of the characters in the range u0030 through u0039 (digits "0" through "9")


我还编写了一个简短的 Python 脚本来确认上述值。 Unicode 字符 0xd8000xdfff也没有工作,因为 Python3 拒绝用这些值创建一个字符串(见 https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF 了解原因),所以这可能在 SQLite C 代码中工作。
import sqlite3
import tqdm
import itertools

with sqlite3.connect(":memory:") as conn:
with conn as cur:
cur.execute("create table test(x);")

strings_to_test = ["{}", "a{}", "{0}{0}", "a{0}{0}", "a({})"]
# make a list to hold the invalid chars for each test item
strings_to_test = {x: list() for x in strings_to_test}

def attempt_insert(string, i, invalid_list):
try:
cur.execute("insert into test values ( :{} );".format(string)
.format(chr(i)),{"{}".format(string).format(chr(i)): 42})
except Exception as e:
invalid_list.append(i)

# 0x10FFFF is the max value for UTF chars
for char_num in tqdm.trange(0, 0x10FFFF):
for string, invalid_char_list in strings_to_test.items():
attempt_insert(string, char_num, invalid_char_list)

def gen_ranges(i):
# from https://stackoverflow.com/a/4629241 with changes for Python3
for a, b in itertools.groupby(enumerate(i), lambda x: x[1] - x[0]):
b = list(b)
yield b[0][1], b[-1][1]

def ranges(invalid_chars):
return "{}".format(["0x{:06x} to 0x{:06x}".format(*range) \
for range in gen_ranges(invalid_chars)])

print("Invalid Single Chars: ie :x were: {}".format(
ranges(strings_to_test["{}"])))
print("Invalid Single Second Chars: ie :ax were: {}".format(
ranges(strings_to_test["a{}"])))
print("Invalid Double Chars: ie :xx were: {}".format(
ranges(strings_to_test["{0}{0}"])))
print("Invalid Double Chars in second pos: ie :axx were: {}".format(
ranges(strings_to_test["a{0}{0}"])))
print("Invalid Parenthesised Chars: ie :abc(x) were: {}".format(
ranges(strings_to_test["a({})"])))

关于SQLITE 标识符的限制字符是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31788990/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com