【问题标题】:Storing SQL return select statement into variable returns wrong value将 SQL 返回选择语句存储到变量中返回错误值
【发布时间】:2017-06-26 14:22:50
【问题描述】:

所以我试图将我的 Select 语句返回到一个变量中。它正在工作,但是它返回了错误的值...

在大多数情况下,它将返回 -7 列的值而不是应有的值。我以为是我的代码,所以我在没有参数的 SQL Server 管理器中尝试了它,得到了几乎相同的结果。

我做错了什么?

这是我的选择语句(如果你不想通过代码):

"SELECT [Item #] FROM dbo.[" + cmbJobName.Text + "] WHERE [Manufacturer] LIKE @Manufacturer AND [Mill Location] LIKE @MillLocation AND [Product Description] LIKE @ProductDescription AND [Weld Seam Type] LIKE @WeldSeamType AND [Outer Dimension] LIKE @OuterDimension AND [Wall Thickness] LIKE @WallThickness AND [Coating] LIKE @Coating AND [Grade] LIKE @Grade AND [Heat] LIKE @Heat AND [ANSI/ASME] LIKE @ANSIASME AND [Purchase Order] LIKE @PurchaseOrder AND [Standard] LIKE @Standard AND [Notes] LIKE @Notes";

这是我的代码:

         try
            {
                using (SqlConnection con = new SqlConnection(Connection.MTRDataBaseConn))
                {
                    con.Open();
                    SqlCommand cmd = new SqlCommand();

                    cmd.CommandText = "SELECT [Item #] FROM dbo.[" + cmbJobName.Text + "] WHERE [Manufacturer] LIKE @Manufacturer AND [Mill Location] LIKE @MillLocation AND [Product Description] LIKE @ProductDescription AND [Weld Seam Type] LIKE @WeldSeamType AND [Outer Dimension] LIKE @OuterDimension AND [Wall Thickness] LIKE @WallThickness AND [Coating] LIKE @Coating AND [Grade] LIKE @Grade AND [Heat] LIKE @Heat AND [ANSI/ASME] LIKE @ANSIASME AND [Purchase Order] LIKE @PurchaseOrder AND [Standard] LIKE @Standard AND [Notes] LIKE @Notes";

                    cmd.Connection = con;
                    SqlParameter pManufactuter = new SqlParameter("@Manufacturer", SqlDbType.VarChar, 50);
                    SqlParameter pMillLocation = new SqlParameter("@MillLocation", SqlDbType.VarChar, 50);
                    SqlParameter pProductDescription = new SqlParameter("@ProductDescription", SqlDbType.VarChar, 50);
                    SqlParameter pWeldSeamType = new SqlParameter("@WeldSeamType", SqlDbType.VarChar, 50);
                    SqlParameter pOuterDimension = new SqlParameter("@OuterDimension", SqlDbType.VarChar, 50);
                    SqlParameter pWallThickness = new SqlParameter("@WallThickness", SqlDbType.VarChar, 50);
                    SqlParameter pCoating = new SqlParameter("@Coating", SqlDbType.VarChar, 50);
                    SqlParameter pGrade = new SqlParameter("@Grade", SqlDbType.VarChar, 50);
                    SqlParameter pHeat = new SqlParameter("@Heat", SqlDbType.VarChar, 50);
                    SqlParameter pAnsiAsme = new SqlParameter("@ANSIASME", SqlDbType.VarChar, 50);
                    SqlParameter pPurchaseOrder = new SqlParameter("@PurchaseOrder", SqlDbType.VarChar, 50);
                    SqlParameter pStandard = new SqlParameter("@Standard", SqlDbType.VarChar, 50);
                    SqlParameter pNotes = new SqlParameter("@Notes", SqlDbType.VarChar, 50);

                    pManufactuter.Value = cmbManufacturer.Text;
                    pMillLocation.Value = cmbMillLocation.Text;
                    pProductDescription.Value = cmbProductDescription.Text;
                    pWeldSeamType.Value = cmbWeldSeamType.Text;
                    pOuterDimension.Value = cmbOuterDimension.Text;
                    pWallThickness.Value = cmbWallThickness.Text;
                    pCoating.Value = cmbCoating.Text;
                    pGrade.Value = cmbGrade.Text;
                    pHeat.Value = txtHeat.Text;
                    pAnsiAsme.Value = cmbANSI.Text;
                    pPurchaseOrder.Value = txtPurchaseOrder.Text;
                    pStandard.Value = cmbStandard.Text;
                    pNotes.Value = txtNotes.Text;

                    cmd.Parameters.Add(pManufactuter);
                    cmd.Parameters.Add(pMillLocation);
                    cmd.Parameters.Add(pProductDescription);
                    cmd.Parameters.Add(pWeldSeamType);
                    cmd.Parameters.Add(pOuterDimension);
                    cmd.Parameters.Add(pWallThickness);
                    cmd.Parameters.Add(pCoating);
                    cmd.Parameters.Add(pGrade);
                    cmd.Parameters.Add(pHeat);
                    cmd.Parameters.Add(pAnsiAsme);
                    cmd.Parameters.Add(pPurchaseOrder);
                    cmd.Parameters.Add(pStandard);
                    cmd.Parameters.Add(pNotes);

                    int result = ((int)cmd.ExecuteScalar());

                    txtReturnFromSelect.Text = result.ToString();

                    cmd.ExecuteNonQuery();
                }
            }
            catch (SqlException ex)
            {
                //catch error
                MessageBox.Show(ex.Message);
            }

注意

数据库目前仅由数字和文本字符串组成,没有空格用于测试目的。例如,我创建了一行只有单词“foo”,另一行只有单词“bar”,而不是“foo”和“bar”的单个字符在数据库的任何其他行中,但它返回了 ID -5 行来自这些行ONLY 包含数字的输入。这发生在我的 SQL 查询和应用程序中。

更新:

我不知道问题出在哪里,但我删除了这些表并使用相同的查询重新创建它们,现在没有任何问题......也许最初创建表时是侥幸?

【问题讨论】:

    标签: c# sql-server tsql select


    【解决方案1】:

    给定代码,您的 sql 语句可能会返回多条记录,因此执行 ExecuteScalar 没有意义,因为它只从数据库返回单个值(第一列第一行)。您最好打开数据阅读器或填充数据集并从那里读取数据。

    【讨论】:

    • 如果要执行一条语句并返回多行,请使用ExecuteReader
    • 我希望它返回多个(使用 if 语句我可以添加一个错误,说明存在现有记录)但在这种情况下,没有记录相互匹配。在这种情况下,会将返回的列/行存储到变量中。
    • 我对你的要求有点困惑。您是否只是检查是否存在符合您的条件的记录?
    • 我正在尝试使用 select 语句并根据在文本框中输入的确切条件找到分配给行的自动递增 ID 号,然后将该 ID # 返回到我程序中的变量中。但是,如果有多个,我会在其中添加一个 if 语句来提醒用户有重复的条目。
    • 为此,我将从查询中加载一个数据集,然后获取第一条记录并检查记录数以确定您是否需要显示警告。
    【解决方案2】:

    如果要执行一条语句并返回多行,请使用ExecuteReader

    var reader = command.ExecuteReader();
    
    while (reader.Read())
    {
        Console.WriteLine(reader["Column1Name"].ToString());
        Console.WriteLine(reader["Column2Name"].ToString());
    }
    

    如果您只想返回第一列的第一个值,那么使用ExecuteScalar 是正确的。但是,不需要您的第二个执行语句(执行非查询)。

    如果 ExecuteScalar 是正确的,但您返回的值不正确 - 您的查询或数据是错误的。首先直接在 SQL Server management Studio 中构建查询以确保其正常工作,然后对其进行编码。

    【讨论】:

    • 我做了,但它返回了相同的值...在查看查询时,我没有发现它有问题。
    • 你能用一些假数据在sqlfiddle.com上复制你的问题吗?
    • 我昨天用上面的答案让它工作了,但是每次我在工作中使用它时 sqlfiddle.com 都会崩溃我的浏览器。
    【解决方案3】:

    您查看过数据吗?停止的数据中是否可能存在未转义的非法字符?

    【讨论】:

    • 是的,在这种情况下,它只是用于测试目的的数字和文本字符串,没有空格。例如,我创建了一行只有单词“foo”,另一行只有单词“bar”,而不是“foo”和“bar”的单个字符在数据库的任何其他行中,但它返回了 ID -5 行输入。
    【解决方案4】:

    我只是在想......你不需要 % 在类似的命令中!在你想要类似的字符串的每一侧都有一个 - % 其中的东西类似于 "%word%"??????

    【讨论】:

    • 更具体地说:...WHERE [Manufacturer] LIKE %@Manufacturer% AND
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2012-12-12
    • 2015-04-13
    • 2012-07-07
    • 2013-04-24
    • 1970-01-01
    相关资源
    最近更新 更多