2013-03-19 75 views
3

我使用的是IDS 11.70。Informix:计数临时表中的列数?

我希望能够获得临时表中的列数,因此在4gl/genero代码中我可以有一个函数,将正确数量的问号放入“放置游标”语句中。

例如,要替换这种代码:

declare put_curs1 cursor for 
    insert into my_temp_table values(?,?,?,?,?,?) 

像这样的东西:

let str = "insert into my_temp_table values (
    format_place_holder_string_for_insert("my_temp_table") CLIPPED, ")" 
prepare put_stment1 from str 
declare put_curs1 cursor for put_stment1 

我们已经做到这一点对于我们普通表,因此,如果表架构应更改为具有更多或更少的列,那么代码将不会因使用放置游标而插入的列数错误而中断。 在此功能常规表,让我们使用的列数:

select count(*) 
    from systables, syscolumns 
    where systables.tabname = table_name 
    and systables.tabid = syscolumns.tabid 

但在试图做到这一点对于临时表,我什么也看不见我加入或什么列表示有多少列在临时表中。这是我到目前为止有:

select * 
FROM sysmaster:systabnames n, sysmaster:systabinfo i, sysmaster:syssessions s 
WHERE sysmaster:bitval(i.ti_flags, "0x0020") = 1 
AND n.dbsname = database_name 
AND i.ti_partnum = n.partnum 
AND s.sid = dbinfo("sessionid") 
AND n.tabname = table_name; 

所以不是select *我需要select count(columns) - 但我在哪里加盟,所以我可以算列?我戳了一下,但无法找到我需要的连接。

感谢, 布莱斯Stenberg发明

回答

1

经典的方式做到这一点是准备“SELECT * FROM不是Temptable”,形容的声明,并得到从描述的列数,然后释放准备好的声明。这涉及到ESQL/C,尽管......或最有可能的。

未经测试的代码 - 与松弛不存在的错误检查:

int cols_in_temp_table(int nargs) 
{ 
    $ char buffer[300]; 
    struct sqlda *u; 
    char tabname[129]; 
    if (nargs != 1) 
     ibm_lib4gl_fatalError(...); 
    popstring(tabname, sizeof(tabname)); 
    sprintf(buffer, "SELECT * FROM %s", tabname); 
    $ PREPARE p FROM :buffer; 
    $ DESCRIBE p INTO u; 
    retint(u.sqld); 
    $ FREE p; 
    free(u); 
    return(1); 
} 

呼叫在I4GL:

DEFINE n INTEGER 

LET n = cols_in_temp_table("the_temp_table") 

的代码将实际上任何表,临时或不工作,所以功能名称是一个轻微的误称。

我找不到sysmaster数据库中的任何内容,它会告诉您有关临时表中的列。这与“没有这样的桌子”并不完全一样,但与其非常接近。

+0

嗨乔纳森,在我们的环境中,我们不使用任何ESQL/C,所以我将无法实现您的解决方案。我们只使用Genero进行编码。数据库必须知道某个地方的临时表中有哪些列,可能有人知道在哪里找到它......谢谢您的回复。问候,布莱斯Stenberg。 – user1840734 2013-03-20 02:37:48

1

我测试了代码低于ifx 11.50 FC9成功。

WARNING:我使用了无证函数。我不知道是否可以安全地使用它在生产...

如何工作:我“转换”行到ROW数据类型;使用名为collectionoutput的内部函数将此行转换为lvarchar,然后计算逗号有多少(列分隔符)。

上一篇:创建/运行函数的权限;临时表必须至少有1行。

--drop function count_cols; 
create function count_cols (cols lvarchar(4000)) returning int ; 
    define i int; 
    define ncols int; 
    define isstring int; 
    let ncols = 1; 
    let isstring = 0; 

    for i = 1 to length(cols) 
    if substr(cols,i,1) = "'" and isstring = 1 then 
     let isstring = 0 ; 
     continue for; 
    end if ; 
    if substr(cols,i,1) = "'" and isstring = 0 then 
     let isstring = 1 ; 
     continue for; 
    end if ; 
    if isstring = 0 and substr(cols,i,1) = ',' then 
     let ncols = ncols+1 ; 
    end if ; 
    end for ; 
    return ncols; 
end function 
; 


--drop table t2; 
create temp table t2 (cod int, desc char(100) default 'test', data datetime year to second default current year to second , number int); 
insert into t2 (cod)values (0); 
insert into t2 (cod)values (0); 
insert into t2 values (1,'teste,teste,teste,teste',current, 0); 

select * from t2; 
select collectionoutput(multiset(select first 1 * from t2 where cod = 1)) from sysmaster:sysdual ; 
select count_cols(collectionoutput(multiset(select first 1 * from t2 where cod = 1))) from sysmaster:sysdual; 

我输出(DBACCESS)

cod  0 
desc test 
data 2013-03-22 11:36:37 
number 

cod  0 
desc test 
data 2013-03-22 11:36:37 
number 

cod  1 
desc teste,teste,teste,teste 
data 2013-03-22 11:36:37 
number 0 

(expression) MULTISET{ROW(1   ,'teste,teste,teste,teste 
                      ','2 
       013-03-22 11:36:37',0   )} 

(expression) 

      4 
+0

嗨,对不起,它已经花了很长时间来回复。 – user1840734 2013-04-04 22:15:45

+0

嗨,对不起,它已经花了很长时间来回复。我试过你的代码,它的工作原理。但是,当我尝试将它与使用select * from myTable创建的实际临时表一起使用到没有日志的temp TmpMyTable中时,我得到错误代码:-9930,Byte,Text,Serial,Serial8或Bigserial数据类型在不允许的集合类型中。“我们在很多表中使用序列,因此它看起来很有前途,但不适合我的情况。我认为无证函数是'collectionoutput'?我可以把这个问题提交给IIUG名单以获得更多的想法。谢谢,布莱斯。 – user1840734 2013-04-04 22:24:09

0

仅供参考 - 如果使用12.10 - 可以创建临时表的真实情况,并得到列从系统表计数。

1)CREATE TABLE yourtemp_chck SELECT * FROM yourtemp where 1 = 2; 2)检查 3列数SYS表)下降yourtemp_chck

虽然我没有试图从一个临时的一个创建一个表但与真正的从实际工作的v12.10。

在任何版本中也可以创建真实表,这样就可以从系统表中获得列数并在此之后下降。我已经在真正旧的4GL中看到过这个。除非没有其他选择,否则不要做某件事。

+0

感谢这个想法 - 当我有时间时,我会放弃它,尽管目前只运行11.70。一旦我尝试过,我会在这里再次发表评论。干杯,布莱斯。 – user1840734 2013-11-12 20:26:08