3

IDS11.70を使用しています。

一時テーブルの列数のカウントを取得できるようにしたいので、4gl / genericoコードで、正しい数の疑問符を「putcursor」ステートメントに入れる関数を使用できます。

たとえば、次の種類のコードを置き換えたいとします。

    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

通常のテーブルに対してはすでにこれを行っているため、テーブルスキーマを変更して列数を増減する必要がある場合でも、putカーソルを使用した挿入で間違った列数でコードが破損することはありません。通常のテーブルのこの関数では、使用する列数を取得します。

   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 )、列を数えるためにどこに参加すればよいのでしょうか。突っついたのですが、必要な参加が見つかりません。

ありがとう、ブライス・ステンバーグ

4

3 に答える 3

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データベースには、一時テーブルの列についての情報が見つかりません。それは「そのようなテーブルはありません」とまったく同じではありませんが、それにかなり近いものです。

于 2013-03-19T23:53:56.383 に答える
1

以下のコードをテストして、ifx 11.50 FC9 で成功しました。

WARNING:文書化されていない関数を使用しました。本番環境で安全に使用できるかどうかはわかりません...

仕組み: 行を ROW データ型に「変換」します。collectionoutput と呼ばれる内部関数を使用して、この ROW を 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
于 2013-03-22T14:46:01.127 に答える
0

参考までに-12.10を使用している場合-一時テーブルの実際のインスタンスを作成し、システムテーブルから列数を取得できます。

1) CREATE TABLE yourtemp_chck SELECT * FROM yourtemp where 1=2; 2) 列の数について sys テーブルを確認します 3) yourtemp_chck を削除します

一時テーブルから実際のテーブルを作成しようとしたことはありませんが、v12.10 では実際のテーブルで動作します。

どのバージョンでも実際のテーブルを作成するだけで、システムテーブルから列数を取得して後でドロップできます。これは本当に古い 4GL で見たことがあります。他に選択肢がない場合を除き、ID が行うことはありません。

于 2013-11-12T11:25:02.120 に答える