尝试在 DynamicParameter 中传递 null 时,Dapper 在参数名称附近报告无效语法
Dapper reporting invalid syntax near parameter name when attempting to pass null in a DynamicParameter
我正在尝试从 table 中获取所有记录,其中某个字段不是空字符串或 null。由于我构建查询的方式,ISNULL
和 COALESCE
不是此处的选项。更改数据库的模式也不是一个选项。
这是我正在 运行 尝试检索记录的代码。
using System;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
namespace DapperMCVE
{
internal class UserFinder
{
public static void Main(string[] args)
{
using (var connection = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True"))
{
connection.Execute(@"IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = 'Users')
CREATE TABLE Users(NullableUserId varchar(50) NULL) ON [PRIMARY]");
connection.Execute(@"DELETE Users");
connection.Execute(@"INSERT INTO Users(NullableUserId)
VALUES(''), (NULL), ('SteveSmith@fake.com'), ('Morgan@totallyreal.org')");
var parameters = new DynamicParameters();
parameters.Add("UserIdNull", (string)null);
parameters.Add("UserIdBlank", "");
try
{
var users = connection.Query(@"SELECT *
FROM Users
WHERE NullableUserId IS NOT @UserIdNull
AND NullableUserId != @UserIdBlank", parameters);
Console.WriteLine(users.ToList());
}
catch (SqlException e)
{
Console.WriteLine(e);
}
Console.ReadKey();
}
}
}
}
抛出的错误是System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near '@UserIdNull'.
我的假设是上面的代码应该复制这个查询:
SELECT *
FROM Users
WHERE NullableUserId IS NOT NULL
AND NullableUserId != ''
但它似乎在做一些更接近
的事情
SELECT *
FROM Users
WHERE NullableUserId IS NOT 'NULL'
AND NullableUserId != ''
如果我将查询更改为
SELECT *
FROM Users
WHERE ISNULL(NullableUserId, '') != ISNULL(@UserIdNull, '')
它工作正常。不幸的是,在这种情况下我不能使用 ISNULL
。
我已经在 SQL Server 2014 和 2016 中复制了它。我们在生产环境中使用 2016。
探查器报告正在执行以下命令 运行:
exec sp_executesql N'SELECT *
FROM Users
WHERE NullableUserId IS NOT @UserIdNull
AND NullableUserId != @UserIdBlank',N'@UserIdNull nvarchar(4000),@UserIdBlank nvarchar(4000)',@UserIdNull=NULL,@UserIdBlank=N''
这让我怀疑这可能是 SQL 服务器本身的问题?
我尝试过的事情(无济于事):
- Casting the parameter to various nullable types
- Using
DBNull.Value
您不能使用 IS NOT 和变量。如果您总是期望 null,则可以对 NullableUserId IS NOT NULL 进行硬编码。
或者使用一些字符串连接创建查询文本
您不能在 sp_executesql 或其他任何地方使用 IS NOT
和参数。
看看这个例子。
此查询 returns 4 条记录来自我的 table :
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT null AND gsm != '''''
所以现在我尝试使用两个值的参数,现在我得到一个错误
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT @UserIdNull AND gsm <> @UserIdBlank',
N'@UserIdNull nvarchar(100),@UserIdBlank nvarchar(100)',
@UserIdNull=NULL,@UserIdBlank=N''
但现在我收到错误
Incorrect syntax near '@UserIdNull'
如果没有 sp_executesql
也会出现同样的错误
declare @UserIdNull nvarchar(100) = null
declare @UserIdBlank nvarchar(100) = ''
SELECT * FROM tblUser WHERE gsm IS NOT @UserIdNull AND gsm <> @UserIdBlank
这会产生同样的错误
因此,您唯一的选择是构建不带 IS NOT
值参数的查询或使用 ISNULL()
在您在问题中构建的查询中,您知道何时编写 IS NOT
然后后跟参数。
我建议简单地写 IS NOT NULL
而不是在那里使用参数
IS NOT @UserIdNull
确实是无效的 SQL 语法.... IS NOT NULL
很好。这不是一个小问题 - 这只是一个 SQL 功能:你需要写合法的 SQL.
My assumption is that the above code should replicate this query:
没有。它使用 参数 。语法被保留。 Dapper 不注入文字。这是非常慎重和正确的。 I wrote about this yesterday,正好。
我正在尝试从 table 中获取所有记录,其中某个字段不是空字符串或 null。由于我构建查询的方式,ISNULL
和 COALESCE
不是此处的选项。更改数据库的模式也不是一个选项。
这是我正在 运行 尝试检索记录的代码。
using System;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
namespace DapperMCVE
{
internal class UserFinder
{
public static void Main(string[] args)
{
using (var connection = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True"))
{
connection.Execute(@"IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = 'Users')
CREATE TABLE Users(NullableUserId varchar(50) NULL) ON [PRIMARY]");
connection.Execute(@"DELETE Users");
connection.Execute(@"INSERT INTO Users(NullableUserId)
VALUES(''), (NULL), ('SteveSmith@fake.com'), ('Morgan@totallyreal.org')");
var parameters = new DynamicParameters();
parameters.Add("UserIdNull", (string)null);
parameters.Add("UserIdBlank", "");
try
{
var users = connection.Query(@"SELECT *
FROM Users
WHERE NullableUserId IS NOT @UserIdNull
AND NullableUserId != @UserIdBlank", parameters);
Console.WriteLine(users.ToList());
}
catch (SqlException e)
{
Console.WriteLine(e);
}
Console.ReadKey();
}
}
}
}
抛出的错误是System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near '@UserIdNull'.
我的假设是上面的代码应该复制这个查询:
SELECT *
FROM Users
WHERE NullableUserId IS NOT NULL
AND NullableUserId != ''
但它似乎在做一些更接近
的事情SELECT *
FROM Users
WHERE NullableUserId IS NOT 'NULL'
AND NullableUserId != ''
如果我将查询更改为
SELECT *
FROM Users
WHERE ISNULL(NullableUserId, '') != ISNULL(@UserIdNull, '')
它工作正常。不幸的是,在这种情况下我不能使用 ISNULL
。
我已经在 SQL Server 2014 和 2016 中复制了它。我们在生产环境中使用 2016。
探查器报告正在执行以下命令 运行:
exec sp_executesql N'SELECT *
FROM Users
WHERE NullableUserId IS NOT @UserIdNull
AND NullableUserId != @UserIdBlank',N'@UserIdNull nvarchar(4000),@UserIdBlank nvarchar(4000)',@UserIdNull=NULL,@UserIdBlank=N''
这让我怀疑这可能是 SQL 服务器本身的问题?
我尝试过的事情(无济于事):
- Casting the parameter to various nullable types
- Using
DBNull.Value
您不能使用 IS NOT 和变量。如果您总是期望 null,则可以对 NullableUserId IS NOT NULL 进行硬编码。 或者使用一些字符串连接创建查询文本
您不能在 sp_executesql 或其他任何地方使用 IS NOT
和参数。
看看这个例子。
此查询 returns 4 条记录来自我的 table :
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT null AND gsm != '''''
所以现在我尝试使用两个值的参数,现在我得到一个错误
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT @UserIdNull AND gsm <> @UserIdBlank',
N'@UserIdNull nvarchar(100),@UserIdBlank nvarchar(100)',
@UserIdNull=NULL,@UserIdBlank=N''
但现在我收到错误
Incorrect syntax near '@UserIdNull'
如果没有 sp_executesql
也会出现同样的错误declare @UserIdNull nvarchar(100) = null
declare @UserIdBlank nvarchar(100) = ''
SELECT * FROM tblUser WHERE gsm IS NOT @UserIdNull AND gsm <> @UserIdBlank
这会产生同样的错误
因此,您唯一的选择是构建不带 IS NOT
值参数的查询或使用 ISNULL()
在您在问题中构建的查询中,您知道何时编写 IS NOT
然后后跟参数。
我建议简单地写 IS NOT NULL
而不是在那里使用参数
IS NOT @UserIdNull
确实是无效的 SQL 语法.... IS NOT NULL
很好。这不是一个小问题 - 这只是一个 SQL 功能:你需要写合法的 SQL.
My assumption is that the above code should replicate this query:
没有。它使用 参数 。语法被保留。 Dapper 不注入文字。这是非常慎重和正确的。 I wrote about this yesterday,正好。