Sql 表值参数默认值或内联传递
参见下面的示例Sql 表值参数默认值或内联传递,sql,sql-server,Sql,Sql Server,参见下面的示例 CREATE TABLE Test ( CD varchar(10) not null ) GO INSERT INTO Test VALUES ('TEST') GO CREATE TYPE [CdTable] AS TABLE (CD varchar(10)); GO CREATE FUNCTION TestTbl ( @x varchar(10), @c CdTable READONLY ) RETURNS TABLE AS RETURN SELECT
CREATE TABLE Test
(
CD varchar(10) not null
)
GO
INSERT INTO Test VALUES ('TEST')
GO
CREATE TYPE [CdTable] AS TABLE (CD varchar(10));
GO
CREATE FUNCTION TestTbl ( @x varchar(10), @c CdTable READONLY )
RETURNS TABLE
AS
RETURN
SELECT t.CD
FROM test t
JOIN @c c ON t.CD = c.CD OR c.CD IS NULL
WHERE t.CD = @x
GO
DECLARE @tt AS CdTable;
INSERT INTO @tt VALUES ('TEST');
SELECT * FROM TestTbl('TEST', @tt);
DELETE FROM @tt;
INSERT INTO @tt VALUES (NULL);
SELECT * FROM TestTbl('TEST', @tt);
GO
CREATE FUNCTION TestNoTbl ( @x varchar(10) )
RETURNS TABLE
AS
RETURN
SELECT *
FROM TestTbl(@x, ???? ) --<<<< how do I pass inline @c parameter with only a single row set to NULL
GO
创建表测试
(
CD varchar(10)不为空
)
去
插入测试值(“测试”)
去
将类型[CdTable]创建为表(CD varchar(10));
去
创建函数TestTbl(@x varchar(10),@c CdTable READONLY)
返回表
作为
返回
选择t.CD
来自测试t
JOIN@c ON t.CD=c.CD或c.CD为空
其中t.CD=@x
去
将@tt声明为CdTable;
插入@tt值(“测试”);
从TestTbl('TEST',@tt)中选择*;
从@tt中删除;
插入@tt值(空);
从TestTbl('TEST',@tt)中选择*;
去
创建函数TestNoTbl(@x varchar(10))
返回表
作为
返回
挑选*
从TestTbl(@x,??)--首先,您不能将默认值分配给表值参数
。相反,您可以更改函数
将内部联接
更改为左侧外部联接
SELECT t.CD
FROM test t
LEFT OUTER JOIN @c c ON t.CD = c.CD
WHERE t.CD = @x
即使@c
不保存任何记录,您也会根据@x过滤器得到结果
更新:基于您的评论
If exists(select 1 from @c)
SELECT t.CD
FROM test t
JOIN @c c ON t.CD = c.CD
WHERE t.CD = @x
Else
SELECT t.CD
FROM test t
WHERE t.CD = @x
谢谢Prdp,但是我想返回与@c连接的行,或者作为特殊情况返回所有行。如果我照你说的做,@c将不再过滤结果。两个问题:1。是否可以在不声明新参数的情况下使用空表调用TestTbl?2.函数中的查询将变得非常复杂,您认为有没有避免代码重复的解决方案?(避免将两个查询都写两次,一个带连接,一个不带连接)提前感谢1。据我所知,您不可能需要声明CdTable
类型的表,您必须在第二个参数2中使用它。我们可以使用动态查询来避免重复,但不幸的是,我们不能在用户定义的函数中使用动态查询。关于第1点,我使用IF(内联函数),因为它在不声明的情况下推断返回表类型(更简单的sql代码管理),但我不能在其中声明CdTable变量。我错了吗?如果我的问题没有解决方案来避免代码重复,那么要么我必须在应用层解决这个问题,要么我必须只定义需要表值参数的“复杂”函数原型,即使不需要它。如果是这样的话,我不喜欢任何一种可用的方法。