Compare strings with trailing spaces in Firebird SQL?
我有一个现有的数据库,其中包含一个带有字符串 [16] 键字段的表。
有些行的键以空格结尾:"16"。
我需要允许用户从"16"更改为例如"16",但也做一个唯一的键检查(即表还没有键="16"的记录)。
我运行以下查询:
1 | SELECT * FROM plu__ WHERE store=100 AND plu_num = '16' |
返回key="16"的行!
如何检查唯一键以便不包括带有尾随空格的键?
编辑:DDL 和 char_length
1 2 3 4 5 | CREATE TABLE PLU__ ( PLU_NUM VARCHAR(16), CAPTION VARCHAR(50), ... |
我怀疑您或您的系统选择了
另外,你可能错了。您声称被选中的行确实包含尾随空白,但我没有看到它。例如,将
另外,如果
屏幕截图底部显示"(NONE)"。我怀疑这是"连接字符集"。这允许与 20 年前制作的程序向后兼容,但今天它非常危险。您必须查阅系统文档,如何将连接字符集设置为 URF-8 或 Windows-1250 或其他有意义的内容。
"如何检查唯一键,以便不包括带有尾随空格的键?"你不。你只是不能可靠地做到这一点,因为不同的事务和不同的程序同时连接。你会检查它,确定你是清楚的,但是在你插入你的行之前 - 其他一些计算机也会插入它。在您的检查和插入两个命令之间,这种差距无法跨越 - 其他任何人也可以做到。它被称为竞争条件。
您必须要求服务器进行检查。
例如,您必须在
中可见
另外,带有空格的值是否正常?将字段转换为整数数据类型并确保安全。
或者如果你想保持文本和非数字,你仍然可以
如果列的数据类型或排序规则对于比较带有和不带有尾随空格的文本没有区别(并且如果您无法更改该数据类型或排序规则),您可以尝试添加标记,例如
文档:
- https://www.firebirdsql.org/refdocs/langrefupd20-distinct.html
- http://www.firebirdtest.com/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-ddl-tbl.html#fblangref25-ddl-tbl-constraints
- http://www.firebirdtest.com/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-ddl-tbl.html#fblangref25-ddl-tbl-altradd
- http://www.firebirdtest.com/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-ddl-trgr.html
- http://www.firebirdtest.com/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-datatypes-chartypes.html
另外,通过 http://www.translate.ru 更详细一点:
- http://firebirdsql.su/doku.php?id=constraint
- http://firebirdsql.su/doku.php?id=alter_table
您也可以查看 http://www.firebirdfaq.org/cat3/
此外,如果您在引入这些检查之前将约束添加到具有先前输入的无效数据的现有表中,您可能会陷入"不可恢复备份"的境地。您必须检查它,并清理旧数据以遵守新引入的约束。
选项#4 详细解释如下。这似乎是数据库设计的一个坏主意!一个人不应该只是"让人们编辑数字以删除尾随空格",一个应该使数据库设计使得没有任何尾随空格的数字,并且没有任何方法将它们插入数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | CREATE TABLE"_NEW_TABLE" ( ID INTEGER NOT NULL, TXT VARCHAR(10) ); SELECT id, txt, '_'||txt||'_', CHAR_LENGTH(txt) FROM"_NEW_TABLE" ID TXT CONCATENATION CHAR_LENGTH 1 1 _1_ 1 2 2 _2_ 1 4 1 _1 _ 2 5 2 _2 _ 2 7 1 _ 1_ 2 8 2 _ 2_ 2 SELECT id, txt, '_'||txt||'_', CHAR_LENGTH(txt) FROM"_NEW_TABLE" WHERE txt = '2' ID TXT CONCATENATION CHAR_LENGTH 2 2 _2_ 1 5 2 _2 _ 2 SELECT id, txt, '_'||txt||'_', CHAR_LENGTH(txt) FROM"_NEW_TABLE" WHERE txt || '+' = '2+' -- WARNING - this PROHIBITS index use on txt column, if there is any ID TXT CONCATENATION CHAR_LENGTH 2 2 _2_ 1 SELECT id, txt, '_'||txt||'_', CHAR_LENGTH(txt) FROM"_NEW_TABLE" WHERE txt = '2' AND CHAR_LENGTH(txt) = CHAR_LENGTH('2') |