Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 表值参数默认值或内联传递_Sql_Sql Server - Fatal编程技术网

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变量。我错了吗?如果我的问题没有解决方案来避免代码重复,那么要么我必须在应用层解决这个问题,要么我必须只定义需要表值参数的“复杂”函数原型,即使不需要它。如果是这样的话,我不喜欢任何一种可用的方法。