我必须将CHAR(1 CHAR)
列更宽,我忘了将列类型更改为VARCHAR2
:
DUPLICADO CHAR(3 CHAR)
当我的PHP应用程序不再能找到完全匹配时,我发现错误,例如:
SELECT *
FROM NUMEROS
WHERE DUPLICADO = :foo
... :foo
为#4
时未找到3-char填充#4
值。但是,我最初在SQL Developer中调试查询时遇到了红鲱鱼,因为在查询中注入原始值会找到匹配项!
SELECT *
FROM NUMEROS
WHERE DUPLICADO = '#4'
为什么我与第二个查询匹配?为什么准备好的陈述有所作为?
答案 0 :(得分:1)
为了扩展我的评论,我在文档中找到了一些解释blankpadded和nonpadded比较的区别:
http://docs.oracle.com/database/121/SQLRF/sql_elements002.htm#BABJBDGB
如果比较中的两个值(等号的两边)都具有数据类型CHAR或NCHAR或是文字字符串,则Oracle选择空白填充比较。这意味着如果长度不同,那么用空白填充短的长度直到长度相同。
如果DUPLICADO
列为CHAR(3)
,则值'#4'
将作为三个字符'#4 '
存储在列中(请注意空白为第三个字符。)当您执行DUPLICADO = '#4'
规则规定Oracle将使用空白填充比较,因此将文字'#4'
空白,直到它与列的长度相同。所以它实际上变成了DUPLICADO = '#4 '
。
但是当你执行DUPLICADO = :foo
时,它将取决于绑定变量的数据类型。如果数据类型为CHAR,它还将执行blankpadded比较。但是如果数据类型是VARCHAR2,那么Oracle将使用非填充比较,然后由您决定是否在必要时进行空白填充。
根据客户端或客户端语言,您可以指定绑定变量的数据类型,从而根据需要进行空白填充或非填充比较。
SQL Developer可能是一种特殊情况,可能不允许您指定数据类型 - 它可能默认绑定变量始终是数据类型VARCHAR2。我不太了解SQL Developer对此有所了解; - )