代码之家  ›  专栏  ›  技术社区  ›  Leonardo M. Ramé

用于强制返回0条记录的ANSI SQL查询

  •  5
  • Leonardo M. Ramé  · 技术社区  · 16 年前

    我正在寻找一个an s i-sql方法来执行一个select查询,但不返回任何记录,而是填充一个tdataset的fields结构。

    我找到的方法是在任何查询中添加“where 1=0”,例如:

    Select Id, name, province
    from customers
    where 1=0
    

    这是一个非常简单的例子,当我必须处理用户输入的查询,然后解析它们,如果已经有了WHERE子句,就删除它,并替换为“1=0”时,它会变得更加复杂。

    如果用户输入的查询中的最后一个子句是WHERE子句,那么完全没有问题,但是对于像这样更复杂的查询呢:

    select
      c.lastname,
      sum(cs.amount)
    from customersales cs
    join customers c on c.idcustomer=cs.idcustomer
    /* where 1=0 */
    group by c.idcustomer, c.lastname
    

    通过使用“where 1=0”方法,在前面的示例中插入它的唯一方法是使用一个相当强大的SQL解析器(请记住,用户可以输入复杂的查询,包括子查询,以及所有这些),他们可以理解在何处包含此字符串。

    有人知道更好的方法吗?我不能使用“限制1”,因为它必须是一个ANSI方式。

    5 回复  |  直到 16 年前
        1
  •  11
  •   Peter Lang    16 年前

    在用户的选择周围添加自己的选择怎么样?

    SELECT * FROM (
    select
      c.lastname,
      sum(cs.amount)
    from customersales cs
    join customers c on c.idcustomer=cs.idcustomer
    /* where 1=0 */
    group by c.idcustomer, c.lastname
    ) x
    WHERE 0=1
    

    编辑: ORDER BY 无法使用该解决方案,但由于没有行,因此可以在必要时尝试从查询中删除该行。

        2
  •  0
  •   Alex Brasetvik    16 年前

    为了将来的参考,在这里人们会有一个不同的目标:请注意,使WHERE子句成为一个矛盾,可能会导致优化器决定根本不执行子计划。因此,如果您需要查询的一些副作用(无论是对缓存进行预热,还是执行一个过程,无论什么),都应该得到建议。-)

        3
  •  0
  •   skamradt    16 年前

    如果您使用的是MSSQL服务器,那么您可以将查询环绕 SET FMTONLY

    SET FMTONLY ON SELECT * FROM tablename SET FMTONLY OFF
    
        4
  •  0
  •   Douglas Tosi    16 年前

    在Firebird中,您可以“准备”语句而不是“执行”。准备只是解析语句并返回字段列表。

        5
  •  0
  •   HeartWare    16 年前

    或使用

    CustomerSQL='SELECT <Fields> FROM <Table>';
    MySQL=Replace(CustomerSQL,'SELECT ','SELECT TOP 0 ');
    

    (可能需要进行一些健全性检查,但您会得到这样的想法——选择Top0将只返回包含记录布局的元数据,而不返回记录数据)。