big*_*mac 6 sql-server stored-procedures table-valued-parameters
使用SQL Server 2012,是否可以省略声明表值参数(TVP)只是为了将其传递给存储过程?下面是一个存储过程(SP)的一个非常简单的例子,它采用TVP和一个工作示例来执行该SP,我必须声明TVP,填充它然后将其传递给SP.我希望能够简单地将人口标准直接传递给EXEC电话.这可能吗?
场景设置:
-- Create a sample Users table
CREATE TABLE Users (UserID int, UserName varchar(20))
INSERT INTO Users VALUES (1, 'Bob'), (2, 'Mary'), (3, 'John'), (4, 'Mark')
-- Create a TVP Type
CREATE TYPE UserIdTableType AS TABLE (UserID int)
-- Create SP That Uses TVP Type
CREATE PROCEDURE GetUsers
@UserIdFilter UserIdTableType READONLY
AS
SELECT * FROM @UserIdFilter WHERE UserID > 2
Run Code Online (Sandbox Code Playgroud)
执行的工作方法:
DECLARE @MyIds AS UserIdTableType
INSERT INTO @MyIds SELECT UserID FROM Users
EXEC GetUsers @MyIds
Run Code Online (Sandbox Code Playgroud)
要求执行的方法:
EXEC GetUsers (SELECT UserID FROM Users)
Run Code Online (Sandbox Code Playgroud)
不,你不能创建一个内联TVP或CAST/CONVERT它.这不是一个"数据类型"之类INT,VARCHAR,DATETIME等; 它是一种完全不同的"表类型".用户定义的表类型(UDTT)只是元数据,用作表变量声明的定义/模式.当这样的表变量用作输入参数时,该用法被认为是TVP(表值参数).但事情仍然是一个表变量,其定义存储在其中tempdb.这是一个物理结构,而不是一个内存结构,你不能CAST或CONVERT一个表,无论是真实的,临时的还是变量的.
虽然问题中给出的示例是简单的,只是为了让想法得以实现,但看起来您的总体目标似乎是代码重用/创建子例程(否则您可以轻松完成SELECT * FROM Users WHERE UserID > 2).不幸的是,T-SQL不允许使用非常优雅/干净的代码,因此您必须接受一定程度的重复和/或笨拙.
但是,如果结果集至少具有必需的字段,则可以为结果集制作稍微通用的处理程序.你可以
在这两种情况下,结构比使用TVP更灵活,因为TVP必须是那些确切的字段.但是,引用假定存在的临时表允许类似于以下内容:
PROC_1
SELECT *
INTO #MyTemp
FROM sys.tables;
EXEC dbo.Proc_4 @StartsWith = 'a', @HowMany = 10;
Run Code Online (Sandbox Code Playgroud)
Proc_2
SELECT *
INTO #MyTemp
FROM sys.columns;
EXEC dbo.Proc_4 @StartsWith = 'bb', @HowMany = 20;
Run Code Online (Sandbox Code Playgroud)
Proc_3
SELECT *
INTO #MyTemp
FROM sys.views;
EXEC dbo.Proc_4 @StartsWith = 'ccc', @HowMany = 33;
Run Code Online (Sandbox Code Playgroud)
Proc_4
SELECT TOP (@HowMany) tmp.*
FROM #MyTemp tmp
WHERE tmp.[name] LIKE @StartsWith + '%'
ORDER BY tmp.[object_id] ASC;
Run Code Online (Sandbox Code Playgroud)