2008-09-23 97 views
4

我有一个函数,我使用名为sqlf(),它模拟预准备语句。比如我可以做这样的事情:“SELECT * FROM users where id IN()”== FAIL

 
$sql = sqlf("SELECT * FROM Users WHERE name= :1 AND email= :2",'Big "John"','[email protected]') ; 

由于种种原因,我不能使用准备好的语句,但我想效仿他们。我遇到的问题是与查询如

 
$sql = sqlf("SELECT * FROM Users WHERE id IN (:1)",array(1,2,3)); 

我的代码工作,但它失败与空数组,例如,下面抛出一个mysql错误:

 
SELECT * FROM Users WHERE id IN(); 

有没有人有任何建议?我应该如何将数组转换并清空为可以注入IN子句的sql?用NULL代替将不起作用。

回答

7

Null是您可以保证不在设置中的唯一值。它怎么不是一种选择?其他任何东西都可以看作潜在的一部分,它们都是价值。

+0

那么我只是试过,它实际上工作。 “IN(NULL)”我认为会和IS NULL做同样的事情,但它们是不同的。感谢你的回答。 – jcampbell1 2008-09-24 00:02:29

0

是否有可能使用sqlf检测空数组并将SQL更改为不具有IN子句?

事实上,在将SQL传递给“真正的”SQL执行程序之前,您可以对SQL进行后处理,以便“IN()”部分被删除,尽管您必须做各种欺骗以查看其他元素必须是什么除去,使:

SELECT * FROM Users WHERE id IN(); 
SELECT * FROM Users WHERE a = 7 AND id IN(); 
SELECT * FROM Users WHERE id IN() OR a = 9; 

将成为:

SELECT * FROM Users; 
SELECT * FROM Users WHERE a = 7; 
SELECT * FROM Users WHERE a = 9; 

这可能变得棘手取决于您的SQL的复杂性 - 你基本上需要一个完整的SQL语言解释器。

-1

我认为可以这样做的唯一方法就是让sqlf()函数扫描一下“IN(”后面是否有一个特定的替换出现,然后如果传入的变量是一个空数组,你知道肯定不会在这一栏:"m,znmzcb~~1",这是一个黑客,当然,但它会工作

如果你想进一步,你可以改变你的功能,以便有不同类型的替换?它看起来像你的函数扫描一个冒号后跟一个数字,为​​什么不添加另一个类型,如@后跟一个数字,这将智能地清空数组(这可以让你不必扫描和猜测如果变量应该是一个数组)

0

如果您的类似准备的函数只是用等价参数替换:1,您可以尝试让查询包含类似(':1')的内容,以便如果:1为空,则会解析为('') ,这不会导致解析错误(但是如果该字段可以有空值,它可能会导致不良行为 - 尽管如果它是一个int,这不是问题)。然而,这不是一个非常干净的解决方案,而且您最好检测数组是否为空,并简单地使用缺少“IN(:1)”组件的替代版本的查询。 (如果这是WHERE子句中唯一的逻辑,那么可能你不想选择所有东西,所以你根本就不会执行查询。)

1

我想说,将一个空数组作为参数传入一个IN )子句是一个错误。调用此函数时,您可以控制查询语法,因此您还应该对输入负责。我建议在调用函数之前检查参数的空白。

0

我会使用零,假设你的“id”列是一个pseudokey自动分配数字。

据我所知,大多数品牌的数据库中的自动密钥生成器都是从1开始的。这是一个约定,而不是要求(自动编号的字段没有在标准SQL中定义)。但是这个约定很普遍,你可以依靠它。因为零可能永远不会出现在你的“id”列中,所以当你的输入数组为空时,你可以在IN()谓词中使用这个值,并且它永远不会匹配。

相关问题