我有以下存储过程,但它没有返回正确的值。我测试了某些东西,似乎%是它无法正常工作的原因。虽然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;
答案 0 :(得分:1)
定义VARCHAR
类型的参数而不给它长度将为您提供一长一个字符的字符串......
ALTER PROCEDURE dbo.UP_getLastUsedIDFromProducts
(
@IDOld VARCHAR, -- exactly ONE character long
@IDLastUpdated INT OUTPUT,
)
这通常不是你想要的 - 所以请总是在你定义VARCHAR
时指定一个长度(无论它是否用作参数,定义一个SQL变量,在CAST
或CONVERT
语句或表定义中使用它!
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')