存储过程无法正常工作

时间:2014-03-05 21:09:09

标签: sql sql-server stored-procedures

我有以下存储过程,但它没有返回正确的值。我测试了某些东西,似乎%是它无法正常工作的原因。虽然ID是数据库中的Int,但由于%,我已将IDOld更改为VARCHAR,因此该程序仍然失败。

我在SQL中测试了该语句,它只返回正确的值,只是存储过程返回了错误的值。此外,我通过在喜欢之后插入'1'来测试它,即使它确实存在于数据库中仍然无法找到该值。所以不确定如何正常工作。

我正在获取旧ID并删除第一个数字,并试图找到类似旧Id的ID,但没有第一个数字,所以示例IDOld = 5623826,IDOld = 623826,它应该返回包含IDOld的值。在数据库中有更多的ID变体,如1623826,2623826,...但我想要最后更新的值,因此使用Max。

ALTER PROCEDURE dbo.UP_getLastUsedIDFromProducts
(
    @IDOld VARCHAR,
    @IDLastUpdated INT OUTPUT,
)
AS
    SELECT @IDLastUpdated = MAX(ID)  
    FROM Products 
    WHERE ID LIKE  '%' + @IDOld

 SqlCommand cmd = new SqlCommand("UP_getLastUsedIDFromProducts");
 cmd.CommandType = CommandType.StoredProcedure;
 cmd.Parameters.Add("@IDOld", SqlDbType.VarChar).Value = tbOriginalID.Text;
 cmd.Parameters.Add("@IDLastUpdated", SqlDbType.Int).Direction = ParameterDirection.Output;

2 个答案:

答案 0 :(得分:1)

定义VARCHAR类型的参数而不给它长度将为您提供一长一个字符的字符串......

ALTER PROCEDURE dbo.UP_getLastUsedIDFromProducts
(
    @IDOld VARCHAR,            -- exactly ONE character long
    @IDLastUpdated INT OUTPUT,
)

这通常不是你想要的 - 所以请总是在你定义VARCHAR时指定一个长度(无论它是否用作参数,定义一个SQL变量,在CASTCONVERT语句或表定义中使用它!

ALTER PROCEDURE dbo.UP_getLastUsedIDFromProducts
(
    @IDOld VARCHAR(20),        -- or whatever fits your needs - just *DEFINE* the length!
    @IDLastUpdated INT OUTPUT,
)

答案 1 :(得分:0)

这是因未指定VARCHAR字段的大小而产生的问题。当你输入 VARCHAR它与VARCHAR(1)相同,因此SQL服务器会将您的输入截断为第一个字符。

阅读此https://sqlblog.org/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length

此外,您希望避免数据类型之间的隐式转换。如果SQL决定转换列而不是参数,这会极大地影响查询的性能。这就是为什么你总是想要匹配两边的数据类型。你永远不希望1 = '1'哪个会起作用但会引起问题。这就是为什么最好这样做1 = CONVERT(INT,'1')

阅读本文 - http://blogs.msdn.com/b/turgays/archive/2013/09/16/data-mismatch-on-where-clause-might-cause-serious-performance-problems.aspx