I produced DDLs to create tables on Oracle using T-SQL since my source tables are in SQL Server. While I was using only 4 tables for testing, it produced 4 DDLs but it repeated the name of the last column and the data type of the table even though The number of columns is correct. For example, TABLE_01 has 6 columns and it repeats the last column name and data type for 6 times.
CREATE TABLE TABLE_01(
ISKEY INT
ISKEY INT
ISKEY INT
ISKEY INT
ISKEY INT
ISKEY INT
);
Here is my code. Does anyone find the reason why it repeats them? I couldn't find the cause. Please help me to solve this problem. I would appreciate your taking time and sharing knowledge for me.
DECLARE @MyList TABLE (Value NVARCHAR(50))
INSERT INTO @MyList VALUES ('TABLE_01')
INSERT INTO @MyList VALUES ('TABLE_02')
INSERT INTO @MyList VALUES ('TABLE_03')
INSERT INTO @MyList VALUES ('TABLE_04')
DECLARE @VALUE VARCHAR(50)
DECLARE @COLNAME VARCHAR(50) = ''
DECLARE @COLTYPE VARCHAR(50) = ''
DECLARE @COLNUM INT = 0
DECLARE @COL_COUNTER INT = 0
DECLARE @COUNTER INT = 0;
DECLARE @MAX INT = (SELECT COUNT(*) FROM @MyList)
-- Loop for Multiple Tables
WHILE @COUNTER < @MAX
BEGIN
SET @VALUE = (SELECT VALUE FROM
(SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) [index] , Value from @MyList) R
ORDER BY R.[index] OFFSET @COUNTER
ROWS FETCH NEXT 1 ROWS ONLY);
SELECT CONCAT('CREATE TABLE ' , REPLACE(UPPER(@VALUE), '_',''), '(')
PRINT 'CREATE TABLE ' REPLACE(UPPER(@VALUE), '_','') '('
SET @COLNUM = 0
SET @COL_COUNTER = 0
;WITH numcol AS
(
select schema_name(tab.schema_id) as schema_name,
tab.name as table_name,
col.column_id,
col.name as column_name,
t.name as data_type,
col.max_length,
col.precision
from sys.tables as tab
inner join sys.columns as col
on tab.object_id = col.object_id
left join sys.types as t
on col.user_type_id = t.user_type_id
where schema_name(tab.schema_id) = 'dbo' AND tab.name = @VALUE
)
SELECT @COLNUM = COUNT(*) OVER (PARTITION BY schema_name, table_name) FROM numcol
-- Loop for Multiple Columns
WHILE @COL_COUNTER < @COLNUM
BEGIN
SET @COLNAME = ''
SET @COLTYPE = ''
SELECT @COLNAME = REPLACE(UPPER(COL.name), '_',''), @COLTYPE = CASE WHEN UPPER(col_type.name) = 'MONEY' THEN ' ' ' NUMBER(19,4)'
WHEN UPPER(col_type.name) = 'REAL' THEN ' ' ' FLOAT(23)'
WHEN UPPER(col_type.name) = 'FLOAT' THEN ' ' ' FLOAT(49)'
WHEN UPPER(col_type.name) = 'NVARCHAR' THEN ' ' ' NCHAR'
ELSE ' ' UPPER(col_type.name)
END
FROM sys.columns COL
INNER JOIN sys.tables TAB
On COL.object_id = TAB.object_id
left join sys.types as col_type
on col.user_type_id = col_type.user_type_id
WHERE OBJECT_NAME(TAB.object_id) = @VALUE
PRINT @COLNAME @COLTYPE
SET @COL_COUNTER = @COL_COUNTER 1
END
PRINT ');'
SET @COUNTER = @COUNTER 1
END
Thank you.
CodePudding user response:
That' a really horrible way to create an SQL script. It's effectively a cursor, and more difficult to write, it's also completely unnecessary.
You can just build the whole thing in one go using STRING_AGG
.
I make no comment on the validity of the result for Oracle, as I don't know Oracle well enough.
DECLARE @table sysname = 'YourTable';
DECLARE @schema sysname = 'dbo';
DECLARE @columns nvarchar(max);
SELECT @columns = STRING_AGG(CONCAT(
' '
REPLACE(UPPER(col.name), '_', ''),
' ',
CASE UPPER(col_type.name)
WHEN 'MONEY' THEN ' NUMBER(19,4)'
WHEN 'REAL' THEN ' FLOAT(23)'
WHEN 'FLOAT' THEN ' FLOAT(49)'
WHEN 'NVARCHAR' THEN ' NCHAR'
ELSE UPPER(col_type.name)
END,
), ',
')
FROM sys.columns col
INNER JOIN sys.tables tab ON col.object_id = tab.object_id
JOIN sys.types as col_type ON col.user_type_id = col_type.user_type_id
JOIN sys.schemas sch ON sch.schema_id = tab.schema_id
WHERE tab.name = @table
AND sch.name = @schema;
SELECT
CONCAT(
'CREATE TABLE ',
REPLACE(UPPER(@table), '_',''),
' (
',
@columns,
'
)'
);