【问题标题】:Use NVARCHAR variables in ASP.NET without declaring their length在 ASP.NET 中使用 NVARCHAR 变量而不声明它们的长度
【发布时间】:2012-03-13 15:28:05
【问题描述】:

我有这个问题

SELECT COUNT(Email) FROM Blacklist WHERE (Email = @email OR (Email like '@%' AND @email like '%' + Email)) AND (CustomerId = @cid OR CustomerId = -1)

我想看看黑名单中的值是否以@开头,如果是,我还想检查参数,看看它是否以黑名单中的值结尾。

(Email like '@%' AND @email like '%' + Email)

如果我像这样在表中一样声明变量,这在 SqlManager 中有效。

declare @email as nvarchar(200) = 'firstname.lastname@xyz.com'
declare @cid as integer = 2

SELECT COUNT(Email) FROM Blacklist WHERE (Email = @email OR (Email like '@%' AND @email like '%' + Email)) AND CustomerId = @cid

黑名单中的值为“@xyz.com”

如果我从 nvarchar(200) 中删除 (200) 部分,它将停止工作。

所以我的问题是如何从 .NET C# 解决这个问题?

db.AddParameter("@email", SqlDbType.NVarChar, email);

【问题讨论】:

  • 为什么要删除长度?您应该总是声明长度。 Email 的最长可能值是多少?您的代码声明不应该与表中列的定义相匹配吗? (博客参考:sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/…
  • 如果您不指定长度,那么您的参数将默认为 1 个字符 的长度。如果您想要 1 个字符以外的内容,您需要指定长度
  • 我很抱歉解释不好,将尝试更新帖子。我声明变量的部分是 SQLmanager 中的一个测试,它正在工作。我希望相同的查询可以从 .NET 工作,这是我的问题。我无法从那里声明长度为 200 的参数。
  • @FredrikBerggren:当然可以!使用db.AddParameter("@email", SqlDbType.NVarChar, 200).Value = email;
  • @Fredrik Berggren:“db”变量是什么类型的?

标签: c# asp.net sql-server tsql sqldbtype


【解决方案1】:

你没有说“停止工作”是什么意思,会发生什么?你得到错误的结果还是错误?为什么要从声明中删除长度?

如果您没有为nvarchar 声明可变长度,则它是1 by default,因此在这种情况下它将具有值N'f';我猜你得到的计数是零而不是你期望的任何数字?注意nvarchar(200)不是“定长”,表示“最多200个字符”; nchar(200) 确实是固定长度的。

在任何情况下,您的问题出在哪里都不是很清楚:字符串长度只是 TSQL 中变量声明的一部分,并且不清楚为什么您不能完全按照上面的说明进行操作。如果这是您的问题,您可以将变量声明为 nvarchar(max) 以避免处理特定长度。

这对您是否有用可能取决于您连接到数据库的方式(您提到了 C#,但您使用的是 ADO、LINQ 还是其他东西?)。

编辑:在 C# 中,如果您的问题中的 db 确实是 SqlDatabase,您可能正在寻找 SqlDatabase.AddParameter 方法的大小参数。

【讨论】:

    【解决方案2】:

    问题是(我与 Fredrik 合作)从 C# 代码执行查询时,它返回 0,即未列入黑名单。从 SQL Managment Studio 执行时,参数的长度可以(必须)指定,返回 1,即被列入黑名单。

    我们的猜测是参数需要指定的大小(与数据库字段相同。但是,即使参数声明为 nvarchar(100),它似乎也可以在 Management Studio 中工作。

    问题依然存在,为什么从代码执行查询返回0?

    【讨论】:

      【解决方案3】:

      我和你有同样的问题,经过多次反复试验/挖掘,我想我已经弄清楚了。

      我制作了一个 SQL Fiddle 来演示这个问题:http://sqlfiddle.com/#!3/c0a51/3

      基本上,即使您可以将 NVARCHAR 设置为任意长度的字符串,它也只能保存定义的字符数。由于默认长度为 1,因此 LIKE 语句中包含的唯一字符是第一个字符,在您的情况下,是电子邮件地址中的第一个字符。

      这基本上是 Marc_S 所说的,但解释了为什么 x = 'ab' 只给了我们 'a'。

      更新

      随着更多的挖掘,我发现如果你像我在 Fiddle 中那样写出你的 SQL 会发生什么。但是,.NET 会根据字符串的长度正确推断 NVARCHAR 的长度并适当地声明变量,因此不会出现这个问题:http://msdn.microsoft.com/en-us/library/hex23w80。因此,您在工作室中的查询与您的应用程序的行为不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-14
        相关资源
        最近更新 更多