【问题标题】:Table-Valued Function using IF statement in SQL Server在 SQL Server 中使用 IF 语句的表值函数
【发布时间】:2016-02-29 07:32:28
【问题描述】:

我有一个学生表包含以下参数

[ID] [nvarchar](50) NOT NULL,
[Firsname] [nvarchar](50) NOT NULL,
[Lastname] [nvarchar](50) NOT NULL,
[Melicode] [nchar](10) NOT NULL,
[City] [nvarchar](50) NOT NULL,
[Province] [nvarchar](50) NOT NULL,
[Active] [int] NULL

我想编写一个名为 Show 的表值函数,它有一个参数作为数字。该函数将如下所示

  • 如果 @number = 1 ,则返回 Student 表中的所有列
  • 如果 @number = 2 ,则仅返回来自 Student 的 City
  • 如果 @number = 3 ,则仅返回来自 Student 的省份

我编写了以下 T-SQL,但它仅适用于 (if (@number = 1))。当用户输入@number 为 2 或 3 时,该功能不起作用。谢谢你

 Create function Show(@number int)
RETURNS @result TABLE
(
    [ID] [nvarchar](50) NOT NULL,
    [Firsname] [nvarchar](50) NOT NULL,
    [Lastname] [nvarchar](50) NOT NULL,
    [Melicode] [nchar](10) NOT NULL,
    [City] [nvarchar](50) NOT NULL,
    [Province] [nvarchar](50) NOT NULL,
    [Active] [int] NULL
) 
AS
BEGIN

    IF  (@number = 1)
         INSERT INTO @result SELECT * from Student 

    IF (@number = 2)
         INSERT INTO @result (City) values ((SELECT City from Student))

     IF (@number = 3)
         INSERT INTO @result (Province) values ((SELECT Province from Student))

    RETURN -- @Players (variable only required for Scalar functions)

END

go
select *from dbo.show(1)

【问题讨论】:

  • 不起作用?不敢相信。

标签: sql sql-server user-defined-functions


【解决方案1】:

情况 2 和 3 的插入语句不正确。插入来自 select 语句的值时不需要 VALUES 关键字。

【讨论】:

  • 我删除了 VALUES 关键字。所以它变成: IF (@number = 2) INSERT INTO @result (City) (SELECT City from Student) 但是,仍然不起作用。
  • 当然你不需要(和)括号 - 这些也应该被删除。
【解决方案2】:
CREATE FUNCTION dbo.Show
(
    @number INT
)
RETURNS @result TABLE
(
    ID NVARCHAR(50),
    Firsname NVARCHAR(50),
    Lastname NVARCHAR(50),
    Melicode NCHAR(10),
    City NVARCHAR(50),
    Province NVARCHAR(50),
    Active INT
)
AS
BEGIN

    IF (@number = 1)
        INSERT INTO @result
        SELECT * FROM dbo.Student

    IF (@number = 2)
        INSERT INTO @result (City)
        SELECT City FROM dbo.Student

    IF (@number = 3)
        INSERT INTO @result (Province)
        SELECT Province FROM dbo.Student

    RETURN

END
GO

SELECT * FROM dbo.Show(2)

【讨论】:

  • @Giorgi Nakeuri,也许你想知道这个答案有什么问题?少了两个字? :)
  • 是的,少了两个字。它也不起作用,因为表中的所有列都不能为空,而且没有人注意到。
  • @Giorgi Nakeuri - 谢谢,不可为空的值是另一个问题。我希望 ID 不能为空。但该功能无法使用。
【解决方案3】:

行不通

INSERT INTO @result (City) 
VALUES ((SELECT City from Student))

要么您将所有值作为标量 SQL 变量或文字 - 然后您可以使用

INSERT INTO @result (City) 
VALUES ('New York')

INSERT INTO @result (City) 
VALUES (@ChosenCity)

您有一个 SELECT 语句来填充值 - 那么您需要以下语法:

INSERT INTO @result (City) 
    SELECT City 
    FROM Student

没有 VALUES 关键字。正如@GiorgiNakeuri 正确指出的那样 - 这将 fail 因为你的所有列都需要一个值(具有 NOT NULL 属性),所以这个插入不能成功 - 你需要提供 all NOT NULL 值(或为每一列定义一个默认值)

【讨论】:

  • 您错过了所有列都不能为空。
  • @marc_s 我希望 ID 不能为空。在我的数据库中将其设为可空并不符合逻辑,但函数无法使用它。我不知道如何解决它。
  • @user3187561: 那么你必须让所有other列都是NULL而不是NOT NULL,你必须找到一种方法来为ID 即使在只提供城市或省值的情况下
【解决方案4】:

返回的表由结果表的声明方式决定。下面的查询有效(在某种意义上),但结果包括 NULLs 的所有列,这些列不是 @number 参数所针对的那些列:

CREATE TABLE dbo.z_Show (str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10))

INSERT z_show
SELECT 1, 1, 1 UNION ALL
SELECT 2, 2, 2 UNION ALL
SELECT 3, 3, 3

CREATE FUNCTION dbo.Show(@number int)
RETURNS @result TABLE
(
    --[ID] [nvarchar](50) NOT NULL,
    --[Firsname] [nvarchar](50) NOT NULL,
    --[Lastname] [nvarchar](50) NOT NULL,
    --[Melicode] [nchar](10) NOT NULL,
    --[City] [nvarchar](50) NOT NULL,
    --[Province] [nvarchar](50) NOT NULL,
    --[Active] [int] NULL
    str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10)
) 
AS
BEGIN
--for debugging|start
--DECLARE @number INT = 3
--DECLARE @result TABLE (str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10))
--for debugging|end

    IF  (@number = 1)
    BEGIN
           --PRINT ('IF (@number = 1)')
         INSERT INTO @result SELECT * from dbo.z_Show
    END

    IF (@number = 2)
    BEGIN
        --PRINT ('IF (@number = 2)')
         INSERT INTO @result (str2) SELECT str2 from dbo.z_Show
    END

     IF (@number = 3)
     BEGIN
           --PRINT ('IF (@number = 3)')
         INSERT INTO @result (str3) SELECT str3 from dbo.z_Show
     END

    RETURN -- @Players (variable only required for Scalar functions)
END

SELECT 'number 1 was passed', *
FROM dbo.show(1)

SELECT 'number 2 was passed', *
FROM dbo.show(2)

SELECT 'number 3 was passed', *
FROM dbo.show(3)

【讨论】:

    【解决方案5】:

    您提到@result 具有所有NOT NULL 列。如果您只想将城市插入该@result,它将把剩余的列作为Null,这就是发生错误的原因。您没有提到 @result 列是 NOT NULL 列,还有一个是。从INSERT 语句中删除VALUES 关键字,因为它正在插入Select 语句

    【讨论】:

    • 是的,它有帮助。但问题是 Result 提供了一个表,其中只有一列有数据,所有其他列都有 NULL 值,看起来不太好。
    • @user3187561 你想用任何其他值替换这些空值吗?
    • 不,我只是希望 NULL 值隐藏在结果中。例如,如果我从用户那里读取@number = 2,则结果应该只是具有值的 City 列,而不是具有 NULL 的其他列。
    猜你喜欢
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多