简体   繁体   中英

IBM Informix How to pass string value in parameter

Could anybody help me with creating the correct SQL query for Informix db? I have the function in which I'm trying to prepare an SQL query from a string as described in the Informix docs

CREATE FUNCTION somefunction( stringval VARCHAR( 32 )) RETURNING INT;
DEFINE c_query varchar(250);
LET c_query = 'select first 1 someid, somevalue from sometable where sname= '||stringval||' order by somevalue;
PREPARE c_stmt
FROM c_query;

DECLARE c_cur CURSOR FOR c_stmt;
OPEN c_cur ;
FETCH c_cur INTO sp_id ;
CLOSE c_cur;
FREE c_cur;
FREE c_stmt;
RETURN sp_id;
END FUNCION;

And when I try to test it, I invoke it as follows:

SELECT * FROM table(functionname('fo'))

But unfortunately I get error message with text:

Column (fo) not found in any table in the query (or SLV is undefined).

What am I doing wrong?

If you want the number corresponding to a name of fo , you'd have to enclose it in quotes, which in turn means you'd need to escape the quotes in the string. You need to read about SQL Injection because what you're proposing is very vulnerable to SQL Injection.

If the object of the exercise is to get the query shown executed, then you should use:

CREATE FUNCTION somefunction(stringval VARCHAR(32)) RETURNING INT;

    DEFINE sp_id INTEGER;

    SELECT FIRST 1 someid
      INTO sp_id
      FROM sometable
     WHERE sname= stringval
     ORDER BY somevalue;

    RETURN sp_id;

END FUNCTION

If the object of the exercise is to use dynamic SQL, then you should consider using placeholders, like this:

CREATE FUNCTION somefunction(stringval VARCHAR(32)) RETURNING INT;

    DEFINE sp_id INTEGER;
    DEFINE c_query varchar(250);
    LET c_query = 'SELECT FIRST 1 someid FROM sometable WHERE sname = ? ORDER BY somevalue';
    PREPARE c_stmt FROM c_query;

    DECLARE c_cur CURSOR FOR c_stmt;
    OPEN c_cur USING stringval;
    FETCH c_cur INTO sp_id;
    CLOSE c_cur;
    FREE c_cur;
    FREE c_stmt;
    RETURN sp_id;

END FUNCTION

Untested on your table. The code I tested was:

CREATE FUNCTION atomic_number(symbol VARCHAR(3)) RETURNING INTEGER;
    DEFINE num INTEGER;
    SELECT atomic_number INTO num FROM elements AS e WHERE e.symbol = symbol;
    RETURN num;
END FUNCTION

and:

CREATE FUNCTION atomic_number(symbol VARCHAR(3)) RETURNING INTEGER;
    DEFINE num INTEGER;
    DEFINE c_query varchar(250);
    LET c_query = 'SELECT FIRST 1 atomic_number FROM elements WHERE symbol = ? ORDER BY atomic_number';
    PREPARE c_stmt FROM c_query;

    DECLARE c_cur CURSOR FOR c_stmt;
    OPEN c_cur USING symbol;
    FETCH c_cur INTO num;
    CLOSE c_cur;
    FREE c_cur;
    FREE c_stmt;
    RETURN num;
END FUNCTION

These run against a 'table of elements' (as in 'Periodic Table'), with structure:

CREATE TABLE elements
(
    atomic_number   INTEGER NOT NULL PRIMARY KEY
                    CHECK (atomic_number > 0 AND atomic_number < 120),
    symbol          CHAR(3) NOT NULL UNIQUE,
    name            CHAR(20) NOT NULL UNIQUE,
    atomic_weight   DECIMAL(8, 4) NOT NULL,
    pt_period       SMALLINT NOT NULL
                    CHECK (pt_period BETWEEN 1 AND 7),
    pt_group        CHAR(2) NOT NULL
                    -- 'L' for Lanthanoids, 'A' for Actinoids
                    CHECK (pt_group IN ('1', '2', 'L', 'A', '3', '4', '5', '6',
                                        '7', '8', '9', '10', '11', '12', '13',
                                        '14', '15', '16', '17', '18')),
    stable          CHAR(1) DEFAULT 'Y' NOT NULL
                    CHECK (stable IN ('Y', 'N'))
);

INSERT INTO elements VALUES(  1, 'H',   'Hydrogen',        1.0079, 1, '1',  'Y');
…
INSERT INTO elements VALUES(118, 'Og',  'Oganesson',     294.2100, 7, '18', 'N');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM