从SQL Server切换到Oracle。如何将字符串连接到循环内的变量?在SQL Server中,我会编写类似
的内容DECLARE @var varchar(max);
WHILE ([I'm doing something or whatever on a table])
BEGIN
SET @var = @var + ' additional text';
END
SELECT @var AS 'result';
到目前为止,这是我在Oracle中的存储过程。 (将其演变为NHibernate的ClassMap文件的autogen)
CREATE OR REPLACE PROCEDURE WWNA.UT_MAPPINGHELPER
(
TABLE_NAME IN ALL_TABLES.TABLE_NAME%TYPE
, OWNER_NAME IN ALL_TABLES.OWNER%TYPE
, CLASS_DEFINITION IN OUT VARCHAR2
)
IS
CURSOR TABLE_INFO_CUR
IS
SELECT
T.TABLE_NAME
, C.COLUMN_NAME
,C.DATA_TYPE
,C.DATA_LENGTH
,C.DATA_PRECISION
,C.NULLABLE
FROM
ALL_TABLES T
JOIN
ALL_TAB_COLUMNS C
ON T.TABLE_NAME = C.TABLE_NAME
AND T.OWNER = C.OWNER
WHERE
T.TABLE_NAME = :TABLE_NAME
AND T.OWNER = :OWNER_NAME;
TABLE_INFO_ROW TABLE_INFO_CUR%ROWTYPE;
build_sql varchar2;
BEGIN
--VARIABLE build_sql varchar2(4000);
:build_sql := '';
OPEN TABLE_INFO_CUR;
LOOP
FETCH TABLE_INFO_CUR INTO TABLE_INFO_ROW;
EXIT WHEN TABLE_INFO_CUR%NOTFOUND;
SELECT (:build_sql || ' ' || TABLE_INFO_ROW.TABLE_NAME || ' ' || TABLE_INFO_ROW.COLUMN_NAME || ' ' || TABLE_INFO_ROW.DATA_TYPE) INTO :build_sql;
END LOOP;
:CLASS_DEFINITION := :build_sql;
--DBMS_OUTPUT.put_line (CLASS_DEFINITION);
END;
由于
答案 0 :(得分:2)
CREATE OR REPLACE PROCEDURE WWNA.UT_MAPPINGHELPER
(
TABLE_NAME IN ALL_TABLES.TABLE_NAME%TYPE
, OWNER_NAME IN ALL_TABLES.OWNER%TYPE
, CLASS_DEFINITION IN OUT VARCHAR2
)
IS
CURSOR TABLE_INFO_CUR
IS
SELECT
T.TABLE_NAME
, C.COLUMN_NAME
,C.DATA_TYPE
,C.DATA_LENGTH
,C.DATA_PRECISION
,C.NULLABLE
FROM
ALL_TABLES T
JOIN
ALL_TAB_COLUMNS C
ON T.TABLE_NAME = C.TABLE_NAME
AND T.OWNER = C.OWNER
WHERE
T.TABLE_NAME = :TABLE_NAME
AND T.OWNER = :OWNER_NAME;
build_sql varchar2(32767);
BEGIN
--build_sql := ''; --Not needed, build_sql is already initialised to NULL
FOR cur_rec IN TABLE_INFO_CUR
LOOP
build_sql := build_sql || ' ' ||
cur_rec.TABLE_NAME || ' ' ||
cur_rec.COLUMN_NAME || ' ' ||
cur_rec.DATA_TYPE;
END LOOP;
CLASS_DEFINITION := build_sql;
--DBMS_OUTPUT.put_line (CLASS_DEFINITION);
END;
您需要定义变量CLASS_DEFINITION
。
使用CURSOR FOR LOOP可以为您打开和关闭光标以及批量提取结果。
答案 1 :(得分:1)
如果要在过程中使用build_sql
值执行此操作,请忽略前导冒号。这是一个典型值,这里不适用。
同时在顶部声明build_sql
变量的长度。这有点令人困惑,因为你可以省去参数的长度,但你需要为声明的变量做长度。
这是你的过程的一个切碎版本,显示build_sql
操纵。另请注意,CLASS_DEFINITION
参数变量不应具有冒号前缀:
CREATE OR REPLACE PROCEDURE WWNA.UT_MAPPINGHELPER
(
TABLE_NAME IN ALL_TABLES.TABLE_NAME%TYPE
, OWNER_NAME IN ALL_TABLES.OWNER%TYPE
, CLASS_DEFINITION IN OUT VARCHAR2
)
IS
...
build_sql varchar2(4000);
BEGIN
build_sql := '';
...
LOOP
build_sql := build_sql || 'whatever';
END LOOP;
CLASS_DEFINITION := build_sql;
END;
另请注意,您不需要build_sql := ''
行 - 变量值将默认为空白。或者,您可以在声明时指定初始值:
CREATE OR REPLACE PROCEDURE WWNA.UT_MAPPINGHELPER
(
TABLE_NAME IN ALL_TABLES.TABLE_NAME%TYPE
, OWNER_NAME IN ALL_TABLES.OWNER%TYPE
, CLASS_DEFINITION IN OUT VARCHAR2
)
IS
...
build_sql varchar2(4000) := 'start of my sql';
BEGIN
...