繁体   English   中英

SQL 服务器 Null 或存储过程的参数中缺少值

[英]SQL Server Null or missing values in the stored procedure's parameters

我有以下存储过程:

CREATE PROCEDURE oc.add_discount (@course_id INT = '',
                                @level VARCHAR(100) = '',
                                @language VARCHAR(100) = '',
                                @series_name VARCHAR(100) = '',
                                @discount DECIMAL(5,4) = 0.0)
AS
BEGIN
    SET @level = ISNULL(@level,'')
    SET @language = ISNULL(@language,'')
    SET @series_name = ISNULL(@series_name,'')
    UPDATE oc.price
    SET discount = @discount,
    --discount based always on the original price
        price = price/(1-discount)*(1-@discount)
    WHERE 
        (@course_id NOT IN (SELECT course_id FROM oc.courses)
            OR course_id IN (@course_id)) AND
        (@level NOT IN (SELECT level FROM oc.level)
            OR course_id IN (SELECT c.course_id 
                    FROM oc.courses c
                    JOIN oc.level l ON c.level_id = l.level_id 
                    WHERE l.level = LOWER(@level))) AND
        (@language NOT IN (SELECT language FROM oc.language)
            OR course_id IN (SELECT c.course_id
                    FROM oc.courses c
                    JOIN oc.language l ON c.language_id = l.language_id
                    WHERE l.language = UPPER(LEFT(@language,1))+LOWER(SUBSTRING(@language,2,LEN(@language))))) AND
        (@series_name NOT IN (SELECT series_name FROM oc.series)
            OR course_id IN (SELECT c.course_id
                    FROM oc.courses c
                    JOIN oc.series s ON c.series_id = s.series_id
                    WHERE s.series_name = @series_name))
    IF @@ROWCOUNT<1
        RAISERROR('Ooops something went wrong. No discount has been added. Avoid NULL or missing values, use '' instead!', 16, 0);
END;

我的问题是该过程在大多数情况下都可以正常工作,但是如果参数是 null 它不会更新任何内容,并且如果中间的参数丢失,我会收到错误消息。 我用一条错误消息解决了这个问题,但我想找到一个更优雅的解决方案。 有人可以帮我吗?

EXEC oc.add_discount 0.1, 1                       ---- this query gives 10% discount for course ID 1
EXEC oc.add_discount 0.1, '', 'beginner', '', ''  ---- this query 10% discount for every beginner course
EXEC oc.add_discount 0.1, NULL, 'beginner', '','' ---- "0 rows affected"
EXEC od.add_discount 0.1, ,'beginner', ,          ---- "Incorrect syntax near ','."
  • 一般优先按名称调用参数:这样可以任意顺序调用参数。

     EXEC oc.add_discount @course_id = 1, @level=''...
  • 如果要使用有序参数调用过程:

    • 您必须按顺序传递参数,并且可以跳过后续参数(前提是它们具有默认值)。

    • 你不能跳过中间的参数。

提出您的问题,如果您想跳过中间参数并使用默认值调用它们,而不是硬编码它们。

EXEC oc.add_discount 0.1, DEFAULT, 'beginner', DEFAULT, DEFAULT

或者,如果你想传递 null 值,传递 null 值并在过程中处理它们

EXEC oc.add_discount 0.1, NULL, 'beginner', NULL, NULL

就您而言,您要处理两次。 我建议您按照以下方式进行。

CREATE PROCEDURE oc.add_discount (@course_id INT = NULL,
                                @level VARCHAR(100) = NULL,
                                @language VARCHAR(100) = NULL,
                                @series_name VARCHAR(100) = NULL,
                                @discount DECIMAL(5,4) = NULL)
as

    SET @level = ISNULL(@level,'')
    SET @language = ISNULL(@language,'')
    SET @series_name = ISNULL(@series_name,'')
    SET @discount = ISNULL(@discount ,0.0)
  • 如果不传值,则填入 NULL 默认值并进行相应设置。
EXEC oc.add_discount 0.1
  • 如果要在中间传递默认值,请使用DEFAULT参数调用
EXEC oc.add_discount 0.1,DEFAULT,1,DEFAULT,DEFAULT,1

据我了解,您想在某些情况下跳过一些参数。 我建议您在执行存储过程时使用以下方法跳过参数。

EXEC od.add_discount @level='',@language='beginner'

但是,根据您的示例,我不建议对 INT 参数使用引号。 您应该考虑改用 NULL。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM