【问题标题】:Use string of numbers as SqlParameter to SQL query resource with IN Operator使用数字字符串作为 SqlParameter 到带有 IN 运算符的 SQL 查询资源
【发布时间】:2018-07-05 19:18:42
【问题描述】:

我正在尝试传递一个字符串 p_strIds,其数值由“,”分隔:

2844099,28441100,2844099,28410.2844105,284411084411111841108441111118411108441111128411128441111128411128441111128411128441111128411141184411115,284111828441115,28411128441115,2841114128441115,284111828441115

字符串用作SqlParameter:

mySqlCommand.Parameters.Add(new SqlParameter("@p_Ids", p_strValores));

由 IN 运算符中的以下资源(添加为资源)查询使用:

UPDATE tbl_Datos 
SET col_Leyenda = (select col_Id from tbl_Leyenda where col_Leyenda = 'T') 
WHERE col_Id in (@p_Ids)

查询和 IN 运算符应该像这样结束:

UPDATE tbl_Datos 
SET col_Leyenda = (select col_Id from tbl_Leyenda where col_Leyenda = 'T') 
WHERE col_Id in (2844099,2844100,2844101,2844102,2844103,2844104,2844105,2844106,2844107,2844108,2844109,2844110,2844111,2844112,2844113,2844114,2844115,2844116,2844117,2844118)

但它说它不能将 nvarchar 转换为 int,我如何格式化参数以在 IN(...Ids...) 处使用

如果我将参数 p_strIds 与 string.Format(queryString, p_strIds) 一起使用,它会起作用:

queryString = UPDATE tbl_Datos SET col_Leyenda = (select col_Id from tbl_Leyenda where col_Leyenda = 'T') WHERE col_Id in ({0})
strSql = string.Format(queryString, p_strValores)
mySqlCommand = new SqlCommand(strSql, m_obSqlConnection);

关于如何在第一种方法中使用 sql 语句作为资源的任何想法?

谢谢

【问题讨论】:

  • 请阅读有关提问的堆栈溢出指南。这个问题缺少很多上下文细节,无法回答。

标签: sql type-conversion resources sqlparameter


【解决方案1】:

tbl_Datos 上的 col_Id 列或表 tbl_Leyenda 中的 col_Leyenda 被声明为数据类型 NVARCHAR。该列中可能有数据,其中至少包含一些非数字字符。

当 SQL 尝试运行您的 WHERE 语句时:WHERE col_Id in (@Ids)

它无法将 col_Id 中的非数字数据转换为 @Ids 中假定为整数的数据列表。

您可以通过在列表中的每个 ID 周围加上单引号来解决此问题。它看起来更像这样:

'2844099','2844100','2844101','2844102','2844103','2844104','2844105','2844106','2844107','2844108','2844109','2844110','2844111','2844112','2844113','2844114','2844115','2844116','2844117','2844118'

也可能是变量@p_Leyenda 作为整数值传入。您也应该尝试将其强制为字符串。与上面的 col_Ids 列表类似。

【讨论】:

  • 感谢您的回答,我已将问题编辑为仅关注第二个参数,因为我将第一个参数强制为带有单引号的字符串并且有效。我将尝试弄清楚如何将单引号放在数字列表中。说到底还是字符串格式问题
  • 用单引号试过了,还是一样,我不明白,最后用 string.format 做的很好。
【解决方案2】:

你需要的是一个拆分函数。

创建一个拆分函数如图here

CREATE FUNCTION [dbo].[SplitString]
(
    @sString nvarchar(2048),
    @cDelimiter nchar(1)
)
RETURNS @tParts TABLE ( part nvarchar(2048) )
AS
BEGIN
    if @sString is null return
    declare @iStart int,
            @iPos int
    if substring( @sString, 1, 1 ) = @cDelimiter 
    begin
        set @iStart = 2
        insert into @tParts
        values( null )
    end
    else 
        set @iStart = 1
    while 1=1
    begin
        set @iPos = charindex( @cDelimiter, @sString, @iStart )
        if @iPos = 0
            set @iPos = len( @sString )+1
        if @iPos - @iStart > 0          
            insert into @tParts
            values  ( substring( @sString, @iStart, @iPos-@iStart ))
        else
            insert into @tParts
            values( null )
        set @iStart = @iPos+1
        if @iStart > len( @sString ) 
            break
    end
    RETURN

END

然后你改变你的查询如下:

UPDATE tbl_Datos 
SET col_Leyenda = (select col_Id from tbl_Leyenda where col_Leyenda = 'T') 
WHERE col_Id in (Select part from SplitString(@p_Leyenda,','))

【讨论】:

    【解决方案3】:

    最后,唯一的办法就是把字符串转成List:

    List<string> p_Ids= p_strValores.Split(',').ToList();
    

    然后将 List 中的每个值转换为 int 并将它们添加到 aux List 例如aux_p_Ids,然后在sql查询中使用:

    UPDATE tbl_Datos SET col_Leyenda = (select col_Id from tbl_Leyenda where col_Leyenda = @p_Leyenda) WHERE col_Id in aux_p_Ids
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 2016-09-25
      • 2016-01-29
      相关资源
      最近更新 更多