使用从整数数组转换的字符串进行查询会导致转换数据类型 smallint 错误

本文关键字:转换 查询 错误 smallint 数据类型 整数 数组 字符串 | 更新日期: 2023-09-27 18:35:16

我有一个整数数组,每个整数对应于数据库中的一个电话ID号。

在我的应用程序中,我将整数数组转换为字符串,如下所示,并将其用作 sql 参数。

    public IList<Phones> GetPhonesByID(int[] idNumbersInts)
    {
        var idNumbersStr = string.Join(",", idNumbersInts);
        var phones = _context.Database.SqlQuery<Phones>(@"
            SELECT Make,
            Model
            FROM PHONES                                 
            WHERE ID_NUM IN (@idNumbers)",
                new SqlParameter("@idNumbers", idNumbersStr),
                ).ToList();
        return phones;
    }

这会导致错误

Conversion failed when converting the varchar value '@idNumbers' to data type smallint

面临的挑战是我正在使用遗留数据库,因此修复必须完全在我的代码中完成,而不是在数据库端完成。

使用从整数数组转换的字符串进行查询会导致转换数据类型 smallint 错误

SQL参数根本不是那样工作的。SQL参数可以帮助您避免SQL注入,但您正在尝试这样做:使用逗号分隔的整数字符串注入SQL。数据库引擎正在尝试将完整的 varchar(字符串)类型参数值转换为 smallint。它不知道也不在乎你是否试图给它一个清单。

现在,使用整数作为方法的参数,您可以非常安全地将它们直接注入到SQL中。

string sqlQuery = String.Format(@"SELECT Make, Model
    FROM PHONES WHERE ID_NUM IN ({0})", idNumberStr);
var phones = _context.Database.SqlQuery<Phones>(sqlQuery).ToList();

如果在其他查询中不使用整数而是使用字符串,则此方法存在安全风险。在这种情况下,下一个方法更好,也可以在您当前的情况下使用。请注意,如果项目列表变得很大,则应考虑先将它们写入临时表中,然后在 WHERE 子句中使用它,以便数据库引擎在尝试分析列表时不会窒息。

var sqlParams = list<SqlParameter>();
int index = 0;
foreach (var id in idNumbersInts)
   sqlParams.Add(new SqlParameter("@p" + (index++), id));
string sqlQuery = String.Format(@"SELECT Make, Model
    FROM PHONES WHERE ID_NUM IN ({0})",
    String.Join(",", sqlParams.Select(p => p.ParameterName).ToArray()));
var phones = _context.Database.SqlQuery<Phones>(sqlQuery,
    sqlParams.ToArray()).ToList();

我认为你不需要执行sql,试试这个:

var phones = _context.Phones.Where(ph => idNumbersInts.Contains(ph.ID_NUM));