面对奇怪的问题:
string sql = $@"SELECT * FROM SearchLogs
WHERE CHECKSUM(@query) = cs_SearchTerm
AND Website = @website";
return await Connection.QueryFirstOrDefaultAsync<SearchLog>(sql,
param: new { query, website });
记录100%存在于数据库中,但我得到null
。 cs_SearchTerm
是computed, int, nullable
字段。然后我试了一下:
DECLARE @term nvarchar(500)
SET @term = @query
SELECT * FROM SearchLogs
WHERE CHECKSUM(@term) = cs_SearchTerm AND Website = @website
但结果相同。然后我尝试分成两个操作:
private async Task<int> SqlCheckSumAsync(string query)
{
string sql = @"SELECT CHECKSUM(@query)";
return await Connection.ExecuteScalarAsync<int>(sql, param: new { query }, transaction: Transaction);
}
string sql = $@"SELECT * FROM Search_Master
WHERE cs_SearchTerm = @checksum
AND Website = @website";
int checksum = await SqlCheckSumAsync(query);
return (await Connection.QueryFirstOrDefaultAsync<Search_Master>(sql,
param: new { checksum, website },
transaction: Transaction));
但仍然没有得到积极的结果。我不知道我做错了什么?为什么我无法将参数传递给SQL scalar
?
答案 0 :(得分:2)
从评论中可以看出:
SELECT * FROM SearchLogs WHERE cs_SearchTerm = CHECKSUM('abc') AND Website = 'ICF'
所以:这告诉我你使用varchar
输入计算了校验和。这非常重要,因为CHECKSUM('abc')
提供了完全不同的答案,而不是CHECKSUM(N'abc')
:
select checksum('abc') as [Ansi], checksum(N'abc') as [Unicode]
给出:
Ansi Unicode
----------- -----------
34400 1132495864
默认情况下,dapper使用nvarchar
(因为.NET字符串是utf-16)。所以我们需要告诉dapper将其作为ANSI字符串传递;幸运的是,这很简单:
return await Connection.ExecuteScalarAsync<int>(sql,
new { query = new DbString { Value = query, IsAnsi = true} },
transaction: Transaction);
Dapper的DbString
类型允许对字符串的发送方式进行细粒度控制,包括它们是unicode还是ANSI,以及它们是固定宽度(如果是这样:什么)或可变宽度。