2013-03-19 73 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