我正在尝试创建一个具有可选参数的存储过程。我按照here列出的说明进行操作。我也引用了这个SO question。但是我一直收到以下错误:
将数据类型varchar转换为int时出错。
当我以
执行它时,它会起作用EXEC sp_get_user {id#}
或
EXEC sp_get_user NULL, {username}
但是
失败了EXEC sp_get_user {username}
存储过程
@id int = NULL,
@username nvarchar(50) = NULL
SELECT
username = COALESCE(a.Username, b.Username),
password = COALESCE(a.Password, b.Password),
signup_date = COALESCE(a.SignedUpOn, b.Signup_Date)
FROM table1 a
FULL OUTER JOIN table 2 b
ON a.ID = b.ID
WHERE ((a.ID = @id OR @id IS NULL)
AND (a.Username = @username OR @username IS NULL)
OR (b.ID = @id OR @id IS NULL)
AND (b.Username = @username OR @username IS NULL))
我尝试添加OPTION(RECOMPILE)
并没有成功。我想让它变得动态,以便其他开发人员可以调用此SP,而无需每次都指定所有参数。如果这会产生影响,他们将通过LINQ进行连接。
答案 0 :(得分:5)
在这种情况下使用命名参数
EXEC sp_get_user @username = {username}
如果两个参数都是可选的,SQL服务器将按位置进行,因此您传入的第一个参数将映射到proc中的第一个
答案 1 :(得分:4)
执行存储过程时,你必须分别按照定义的参数顺序,这就是第一个和第二个语句正常工作的原因,在你传递id的第一个EXEC sp_get_user {id#}
中忽略了用户名,然后它采用定义的默认值。此外,在您的第二个语句EXEC sp_get_user NULL, {username}
中,您为id指定了NULL,并且您传递了username参数的值,这也是它工作的原因。
另一方面,第三个EXEC sp_get_user {username}
不起作用,因为SQL Server将您的参数{username}
视为id值,这就是它尝试将其转换为整数的原因,当然它会失败。相反,您必须在传递其值时指定参数名称,请参阅以下代码:
EXEC sp_get_user @username = {username}
答案 2 :(得分:3)
嗯,是的,显然你的最后一次尝试都会失败。
您的存储过程需要两个参数,按顺序:
@id INT
@username NVARCHAR(50)
如果您只是使用单个参数调用存储过程,那么该参数将映射到@id
- 因此它必须是INT
。
如果您只想使用一个用户名值来调用存储过程,则需要使用命名参数 - 您不能依赖该位置(因为第一个且唯一的参数将是始终匹配@id
)
EXEC sp_get_user @username = {username}