【问题标题】:Using placeholders in Informix SQL queries在 Informix SQL 查询中使用占位符
【发布时间】:2018-01-17 07:23:23
【问题描述】:

如果我需要两次分配输入参数之一,如何在动态 SQL 字符串中使用占位符?以下代码不起作用。

CREATE FUNCTION somefunc( p_name VARCHAR( 32 ), p_id INT, p_weight INT ) RETURNING INT;

    LET sp_id = 0;
    LET somearea=12;


    LET c_query ='SELECT FIRST 1 pr_id FROM sometable n WHERE n.pr_id> ? and n.pr_weight = ? ( UPPER( n.sname ) LIKE %UPPER(?))'||
    ' OR( UPPER(?) LIKE %UPPER( n.name)) ORDER BY 1, 2;';

    PREPARE c_stmt
    FROM c_query;

    DECLARE c_cur CURSOR FOR c_stmt;

    OPEN c_cur USING p_id, p_weight, p_name, p_name ;

    FETCH c_cur INTO sp_id;

    CLOSE c_cur;

    FREE c_cur;

    FREE c_stmt;

    RETURN sp_id;

END FUNCTION;

【问题讨论】:

  • 忽略动态SQL,字符串包含一堆乱码,从? ( UPPER( n.sname ) LIKE %UPPER(?))'中的第一个?之后开始。如果你用一个值替换了那个问号(比如13),那么剩下的代码就没有意义了;你不能在那里有一个开放的括号。您不能提供动态 SQL 语句的结构元素作为占位符。您不能提供表名或列名或函数名;您只能提供要在 SQL 中使用的值。如果您需要表、列或函数名称,则必须将它们“编辑”到您准备的 SQL 字符串等中。
  • 对此我真的很抱歉,但我实际上不明白你的文字。您能否提供一些小例子来说明占位符如何工作以及它们如何映射到参数和变量
  • 今晚不行;已经过了就寝时间一个小时。如果早上没有其他人做任何事情,我会尝试。我注意到我对您其他问题的回答有一些动态 SQL,其中包含占位符。
  • 首先我需要知道你在动态 sql 下到底是什么意思))。我以为我的示例还包含动态 SQL。

标签: sql database syntax informix


【解决方案1】:

嗯...不太确定完全理解这个问题(或者那个 SQL 的目的,希望这是我们的测试,因为它确实看起来很奇怪)

无论如何,这是您的 SPL,语法正确:

D:\infx\ids12>cat 1.sql
DROP TABLE sometable;
CREATE TABLE sometable  (name varchar(32), sname varchar(32), pr_id int, pr_weight int);

INSERT INTO sometable VALUES ('test','test',1,100);
INSERT INTO sometable VALUES ('tESt','tESt',2,200);
INSERT INTO sometable VALUES ('another','another',3,300);

DROP FUNCTION somefunc;
CREATE FUNCTION somefunc( p_name VARCHAR( 32 ), p_id INT, p_weight INT ) RETURNING INT;
    DEFINE sp_id int;
        DEFINE c_query varchar(200);

    LET sp_id = 0;
        LET c_query ="SELECT FIRST 1 pr_id FROM sometable n WHERE n.pr_id> ? and n.pr_weight = ? and ( UPPER( n.sname ) LIKE UPPER('%'||?||'%')) OR( UPPER('%'||?||'%') LIKE UPPER( n.name)) ORDER BY 1";

    PREPARE c_stmt
    FROM c_query;
    DECLARE c_cur CURSOR FOR c_stmt;
    OPEN c_cur USING p_id, p_weight, p_name, p_name ;
    FETCH c_cur INTO sp_id;
    CLOSE c_cur;

    FREE c_cur;
    FREE c_stmt;
    RETURN sp_id;

END FUNCTION;

--SELECT FIRST 1 * FROM sometable n WHERE n.pr_id> 1 and n.pr_weight = 200 and ( UPPER( n.sname ) LIKE UPPER('%'||'TEST'||'%')) OR ( UPPER('%'||'TEST'||'%') LIKE UPPER( n.name)) ORDER BY 1;

EXECUTE FUNCTION somefunc('TEST',1,200);

D:\infx\ids12>dbaccess stores7 1.sql
Database selected.
Table dropped.
Table created.
1 row(s) inserted.
1 row(s) inserted.
1 row(s) inserted.
Routine dropped.
Routine created.
(expression)
           2
1 row(s) retrieved.
Database closed.
D:\infx\ids12>

我认为 Jonathan 在谈论动态 SQL 时所指的是您不需要在 SPL 中使用占位符 (?) 构建或准备 SELECT 语句。您可以执行大多数“任何”SQL 语句。 上面的 SPL 可以重写为:

D:\infx\ids12>cat 2.sql
DROP FUNCTION somefunc_simple;

CREATE FUNCTION somefunc_simple( p_name VARCHAR( 32 ), p_id INT, p_weight INT )
RETURNING INT;
        DEFINE sp_id int;

        LET sp_id=(SELECT FIRST 1 pr_id  FROM sometable n WHERE n.pr_id> p_id and n.pr_weight = p_weight and ( UPPER( n.sname ) LIKE UPPER('%'||p_name||'%')) OR ( UPPER('%'||p_name||'%') LIKE UPPER( n.name)));

        RETURN sp_id;
END FUNCTION;

EXECUTE FUNCTION somefunc_simple('TEST',1,200);

D:\infx\ids12>dbaccess stores7 2.sql
Database selected.
Routine dropped.
Routine created.
(expression)

           2
1 row(s) retrieved.
Database closed.
D:\infx\ids12>

阅读 Informix SQL 指南

https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.sqls.doc/sqls.htm

它应该让您了解如何编写 Informix SQL 和 SPL 以及支持哪些功能。

另外,这里解释了动态 SQL:

https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.esqlc.doc/ids_esqlc_0528.htm

【讨论】:

  • 非常感谢,但在您的上一个示例中,您没有使用 order by 语句
  • 仍然不太明白你想用 SPL 实现什么,但你不能像上面那样在单例 SQL 中使用 ORDER BY。
  • 我需要在 foreach 正文中获取 select 查询的结果,但由于 foreach 不支持其中的 select 语句,我将 select 查询包装到函数中。如果我需要将查询结果保存到变量中如何正确?
  • 我现在更困惑了 ;) 你是说这个 FOREACH 吗? (ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/…) 因为原始 SPL 中没有 FOREACH。
  • 是的,确实如此。 informix db 上下文中的所有问题;但是我已经成功地完成了我的任务。感谢您的帮助。
猜你喜欢
  • 2023-03-17
  • 2014-03-03
  • 2020-06-09
  • 2021-11-25
  • 2020-06-16
  • 2021-07-12
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多