2

我想创建一个具有可选参数的存储过程。我遵循列出的说明here。我也参考了SO question。不过,我不断收到以下错误:SQL存储过程中的可选参数

Error converting data type varchar to 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

通过google找到的旧问题 - 为什么将此标记为LINQ? “通过LINQ连接”是LINQ的唯一参考 – 2014-07-23 09:43:10

回答

5

命名参数

EXEC sp_get_user @username = {username} 

如果两个参数都是可选的,SQL Server将通过位置去,所以要传递的第一个将映射到第一个在proc

3

嗯,是的,显然你最后一次尝试会失败。

你的存储过程需要两个参数,按照这个顺序:

  1. @id INT
  2. @username NVARCHAR(50)

如果你只是简单地用一个参数调用存储过程,则该参数会映射到@id - 因此它需要是INT

如果你想打电话给你的存储过程与用户名只是一个单一的值,则需要使用命名参数 - 你不能靠上的位置(因为第一个也是唯一一个参数将始终匹配@id

EXEC sp_get_user @username = {username} 
4

当执行你必须分别定义为符合该参数顺序存储过程,这也就是为什么第一和第二语句工作正常,在第一个EXEC sp_get_user {id#}你传递的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}