无法将列名设置为等于用户确定的变量

时间:2015-06-11 11:24:55

标签: sql teradata

我正在创建一个结果集,我希望列名在运行时期间等于变量名。那可能吗 ?我该怎么做?

在下面的示例中,用户在运行查询之前选择日期(myDate)(例如2015-06-11)。我希望列名称为该日期(2015-06-11)。我怎么做?仅供参考:我正在使用Teradata。

    SELECT 
    table_A.Cnt as ?myDate 
/* I can't write ?myDate like that. I also tried to convert it to a string */

    FROM
    (
    SELECT COUNT(*) AS Cnt FROM A
       WHERE theDate=?myDate 
     ) AS table_A

1 个答案:

答案 0 :(得分:1)

你要做的是参数化一个对象(或一个对象的名称),而不是参数化一个值,当你想出这个想法时,这似乎是直截了当的,但它有点难以实现。 。

首先,只有一个SP允许您动态编写和执行SQL,这就是您在这里所做的。其次,它有点冗长。第三,它打开了SQL注入问题,因为您正在将参数从用户滑入SQL然后执行它,因此请谨慎行事并尽力避免漏洞破坏您的系统。

CREATE PROCEDURE paramMyField
(
    IN myDate Date, 

    --This has to be less than 30 otherwise Teradata will be angry. 
    --I would set it low just to keep injection possibilities to minimum
    IN fieldName VARCHAR(10) 
)

--Tell it how many result sets this thing is going to return:
DYNAMIC RESULT SETS 1

--Set the security (using the security of the bloke that sets this thing off, if you don't trust them, neither do I)
SQL SECURITY INVOKER

BEGIN

    --We'll need a variable to hold the dynamically generated sql statement
    DECLARE dynSQL VARCHAR(5000);

    --And we'll need a cursor and a statement
    DECLARE dynCursor CURSOR WITH RETURN ONLY FOR dynStatement;

    SET dynSQL = '  
        SELECT 
            table_A.Cnt as ' || fieldName || '
        FROM
            (
            SELECT COUNT(*) AS Cnt FROM A
               WHERE theDate = DATE ''' || myDate || '''
             ) AS table_A;';

    --Now to prep the statement
    PREPARE dynStatement FROM dynSQL;

    --And open the cursor (we will open and not close it so it's sent back as a resultset
    OPEN dynCursor;

END;

那里发生了很多事情,但基本上它是一个存储过程,它接受两个参数(字段的日期和名称)并吐出一个记录集,它是SQL语句的结果使用动态命名的字段。它通过使用动态SQL语句来完成此操作。

这是通过运行类似:

执行的
CALL paramMyField(DATE '2015-06-15', 'Whatever');