我有一个oracle sql语句。
表数据如下所示:
FORM_NO | PART_NO | CHUTTER_ID
1 | ABC | 1,3,9,12,15
我有 PHP 变量
$get_q = "3";
现在我想查询:
$q = oci_parse($c1, "SELECT * FROM tb_test WHERE CHUTTER_ID IN '$get_q'");
oci_execute($q);
查询结果为空。
谁知道,如何解决这个问题?
你可以像这样编写测试:
"SELECT * FROM tb_test WHERE ',' || CHUTTER_ID || ',' LIKE '%,$get_q,%'"
这会将逗号附加到 CUTTER_ID 的值,使其变为类似以下内容:
,1,3,9,12,15,
然后,它会检查上述内容是否与此模式匹配:
%,3,%
其中%
表示 0 到任意数量的字符。需要额外的逗号来确保使用此方法也能找到 1 和 15。
关于原始查询
您的查询无效,因为 IN
运算符要求正确的参数是括号中的列表,就像 (3)
一样,不带引号。但即使你这样做,你也会得到这样的表达:
CUTTER_ID IN (3)
这就像在说:
'1,3,9,12,15' IN (3)
但这没有意义。您可能想要测试相反的情况:
3 in (1,3,9,12,15)
但遗憾的是,数据库字段CUTTER_ID
不适合这样的构造。幸运的是,LIKE
的替代方案可以奏效。
SQL 注入
请注意,如果示例中的值"3"派生自用户输入,则您的代码容易受到 SQL 注入的影响。为避免这种情况,请通过 oci_bind_by_name
绑定值,如下所示:
$q = oci_parse($c1, "SELECT * FROM tb_test
WHERE ',' || CHUTTER_ID || ',' LIKE '%,' || :p1 || ',%'");
oci_bind_by_name($stid, ':p1', $get_q);
oci_execute($q);
数据库设计
最后,一个数据库字段中的值列表并不是良好数据库模型的标志。这是未规范化的数据库的示例。它甚至不符合第一种规范化形式。
如果您可以控制数据库设计,请考虑按照上面链接的文章中的建议对其进行更改。它将提高您的查询速度。