我想创建存储过程并动态生成表的insert语句。存储过程的输入参数应为schema, table name, @col1, @col2, ..., @colN
。该存储过程应该从另一个服务器获取1个随机记录,并且基于该记录应该生成INSERT语句。 @col1, @col2, ..., @colN
参数是可选的,以防您想要用您需要的值覆盖原始值。
插入记录看起来应该是这样的:
INSERT INTO schema_name.table_name VALUES (
col1,
col2,
...,
colN)
VALUES (
COALESCE(@col1, 'col1_value'),
COALESCE(@col2, 'col2_value'),
...,
COALESCE(@colN, 'colN_value')
);
目前我无法实现如何获取真实数据并将其置于声明中。我已经做的是:
CREATE PROCEDURE dbo.GenerateSampleDataInsertSP
@SchemaName VARCHAR(255),
@TableName VARCHAR(255)
AS
SET NOCOUNT ON;
DECLARE @sql VARCHAR(MAX) = '',
@columns VARCHAR(MAX) = '',
@columnsWithCoalesce VARCHAR(MAX) = '';
SELECT c.name
INTO #column
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.columns c ON c.object_id = t.object_id
JOIN sys.types tt ON c.system_type_id = tt.system_type_id
WHERE t.name = @TableName
AND s.name = @SchemaName
AND tt.name NOT IN ( 'timestamp' );
SET @columns = NULL;
SELECT @columns = ISNULL(@columns + ', ', '') + name
FROM #column;
SET @sql = 'SELECT TOP 1 ' + @columns + ' FROM AnotherDatabase.' + @SchemaName + '.' + @TableName + ' ORDER BY NEWID();';
SET @sql = 'INSERT INTO [' + @SchemaName + '].[' + @TableName + '] (' + @columns + ') VALUES ();';
SELECT @sql;
我不关心理想的代码或解决方案。我需要结果,那就是它。
更新:
- 示例#1
USE tempdb
GO
/*CREATE PROCEDURE dbo.GenerateSampleDataInsertSP ...*/
CREATE TABLE dbo.Employee (ID INT, EmployeeName VARCHAR(255));
INSERT INTO dbo.Employee VALUES (1, 'John Smith');
EXEC dbo.GenerateSampleDataInsertSP @SchemaName = 'dbo', @TableName = 'Employees';
------------------------ EXPECTED OUTPUT OF THE PROCEDURE (NOT THE ACTION, BUT PLAIN TEXT) ------------------
INSERT INTO dbo.Employee
(
ID,
EmployeeName
)
VALUES
(
COALESCE(@ID, '1'),
COALESCE(@EmployeeName, 'John Smith')
);
- 示例#2
USE tempdb
GO
/*CREATE PROCEDURE dbo.GenerateSampleDataInsertSP ...*/
CREATE TABLE dbo.Orders (ID INT, OrderNbr VARCHAR(10), OrderDate DATE, CustomerID ID);
INSERT INTO dbo.Orders VALUES (7, '12345678', GETDATE(), 1024);
EXEC dbo.GenerateSampleDataInsertSP @SchemaName = 'dbo', @TableName = 'Orders';
------------------------ EXPECTED OUTPUT OF THE PROCEDURE (NOT THE ACTION, BUT PLAIN TEXT) ------------------
INSERT INTO dbo.Orders
(
ID,
OrderNbr,
OrderDate,
CustomerId
)
VALUES
(
COALESCE(@ID, '7'),
COALESCE(@OrderNbr,'12345678'),
COALESCE(@OrderDate, '2015-07-05'),
COALESCE(@CustomerId, '1024')
);
答案 0 :(得分:0)
好的,我会回答我自己的问题。正如我所说,我不关心代码的美感和性能,我只需要结果,所以任何提供更优雅解决方案的人都会被接受为解决方案。这是代码:
CREATE PROCEDURE dbo.GenerateSampleDataInsertSP
@SchemaName VARCHAR(255),
@TableName VARCHAR(255)
AS
SET NOCOUNT ON;
IF EXISTS ( SELECT name
FROM tempdb.sys.tables
WHERE name LIKE '%##record%' )
BEGIN
DROP TABLE ##record;
END;
DECLARE @sql VARCHAR(MAX) = '',
@columns VARCHAR(MAX) = '',
@columnsWithCoalesce VARCHAR(MAX) = '';
SELECT c.name
INTO #column
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.columns c ON c.object_id = t.object_id
JOIN sys.types tt ON c.system_type_id = tt.system_type_id
WHERE t.name = @TableName
AND s.name = @SchemaName
AND tt.name NOT IN ( 'timestamp' );
SET @columns = NULL;
SELECT @columns = ISNULL(@columns + ', ', '') + name
FROM #column;
SET @sql = 'SELECT TOP 1 ' + @columns + ' INTO ##record FROM AnotherDataBase.' + @SchemaName + '.' + @TableName + ' ORDER BY NEWID();';
EXEC (@sql);
SET @sql = 'INSERT INTO [' + @SchemaName + '].[' + @TableName + '] (' + @columns + ') VALUES (';
DECLARE @columnsCur CURSOR, @ColumnName VARCHAR(255), @tmpValue VARCHAR(MAX), @sqlCommand nvarchar(1000);
SET @columnsCur = CURSOR FOR
SELECT name
FROM #column;
OPEN @columnsCur;
FETCH NEXT
FROM @columnsCur INTO @ColumnName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sqlCommand = 'SELECT @value=CAST(' + @ColumnName + ' AS VARCHAR(MAX)) FROM ##record;'
EXECUTE sp_executesql @sqlCommand, N'@value VARCHAR(MAX) OUTPUT', @value=@tmpValue OUTPUT
SET @sql = @sql + 'COALESCE(@'+ @ColumnName +', ''' + @tmpValue + '''),';
FETCH NEXT
FROM @columnsCur INTO @ColumnName;
END;
CLOSE @columnsCur;
DEALLOCATE @columnsCur;
SET @sql = @sql + ');'
SET @sql = REPLACE(@sql, ',);', ');');
SELECT @sql;
GO