MS SQL 2008 支持 TVP:一种将数据批量上传到存储过程进行处理的有用功能。
是否可以利用现有的表定义,而不是创建用户定义的类型?例如,是否可以创建具有以下签名的存储过程?
CREATE PROCEDURE usp_InsertProductionLocation
@TVP **LocationTable** READONLY
Run Code Online (Sandbox Code Playgroud)
文档似乎表明这是不可能的。
示例代码
/*
Sample code from:
http://msdn.microsoft.com/en-us/library/bb510489.aspx
*/
USE AdventureWorks2008R2;
GO
/* Create a table type. */
CREATE TYPE LocationTableType AS TABLE
( LocationName VARCHAR(50)
, CostRate INT );
GO
/* Create a procedure to receive data for the table-valued parameter. */
CREATE PROCEDURE usp_InsertProductionLocation
@TVP LocationTableType READONLY
AS
SET NOCOUNT ON
INSERT INTO [AdventureWorks2008R2].[Production].[Location]
([Name]
,[CostRate]
,[Availability]
,[ModifiedDate])
SELECT *, 0, GETDATE()
FROM @TVP;
GO
/* Declare a variable that references the type. */
DECLARE @LocationTVP
AS LocationTableType;
/* Add data to the table variable. */
INSERT INTO @LocationTVP (LocationName, CostRate)
SELECT [Name], 0.00
FROM
[AdventureWorks2008R2].[Person].[StateProvince];
/* Pass the table variable data to a stored procedure. */
EXEC usp_InsertProductionLocation @LocationTVP;
GO
/*
The following is not part of the original source code:
*/
CREATE TABLE LocationTable(
LocationName VARCHAR(50)
, CostRate INT );
GO
Run Code Online (Sandbox Code Playgroud)
Aar*_*and 19
不,您不能利用现有的表定义,您需要定义一个显式类型。这是在 2007 年提出的要求,并因“无法解决”而被关闭,但我仍然强烈鼓励您投票并发表评论,描述您的用例以及这将如何帮助您的业务提高生产力。您甚至可以指出这个问题来演示尝试和自动化这个过程是多么乏味。
不过,您今天可以动态地执行此操作……例如,对于您的简单定义:
-- you would pass these two in as parameters of course:
DECLARE
@TableName SYSNAME = N'LocationTable',
@TypeName SYSNAME = N'LocationTypeTable';
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql = @sql + N',' + CHAR(13) + CHAR(10) + CHAR(9)
+ QUOTENAME(c.name) + ' '
+ s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN
'(' + CONVERT(VARCHAR(12), (c.max_length/
(CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END))) + ')'
ELSE '' END
-- need much more conditionals here for other data types
FROM sys.columns AS c
INNER JOIN sys.types AS s
ON c.system_type_id = s.system_type_id
AND c.user_type_id = s.user_type_id
WHERE c.[object_id] = OBJECT_ID(@TableName);
SELECT @sql = N'CREATE TYPE ' + @TypeName
+ ' AS TABLE ' + CHAR(13) + CHAR(10) + '(' + STUFF(@sql, 1, 1, '')
+ CHAR(13) + CHAR(10) + ');';
PRINT @sql;
-- EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)
结果:
CREATE TYPE LocationTypeTable AS TABLE
(
[LocationName] varchar(50),
[CostRate] int
);
Run Code Online (Sandbox Code Playgroud)
免责声明:这不涉及 MAX 类型、数字的精度和小数位数等所有类型的其他内容。最终解决方案必须更加健壮以考虑所有潜在的列定义,但这应该给您一个开始。
在 SQL Server 2012 中,有新的 DMV 和存储过程,可以更轻松地从现有表(或存储过程或什至即席查询)派生列元数据,而不必处理针对 sys.types 和 sys 的所有条件逻辑。列。我在 12 月的博客中简要介绍了这些增强功能。它仍然很乏味,但它介于上面可怕的无法维护的意大利面和只能说“作为 [table x] 的副本”的能力之间......
归档时间: |
|
查看次数: |
8305 次 |
最近记录: |