【问题标题】:C# connected to SQL not returning a valueC#连接到SQL不返回值
【发布时间】:2019-05-20 15:14:54
【问题描述】:

我使用 C# 连接到 SQL Server。现在,我必须做 3 个选项。一个是执行一个程序,效果很好,第二个是检索一些数据,这也完成了最后一个选项是选择一个特定的国家,由用户选择,并显示平均得分位于该国家/地区的餐厅。

现在,当我测试它时,查询可以在 SSMS 上运行。但是,当我尝试像其他 2 个选项一样运行它时,它给了我一个连接错误。

下面的代码是第二个有效选项的 C# 代码:

public static void showStatistics()
{
    string connetionString = "Data Source=DESKTOP-RV4VR9I;Initial 
Catalog=Assignment;User ID=Jake;Password=1234;Integrated Security=True";

    SqlConnection conn = new SqlConnection(connetionString);
    SqlCommand mySQL = new SqlCommand("BEGIN TRANSACTION SET     
TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT TOP 1 country, score, 
year FROM main.[stats] ORDER BY [Statistics Generated] DESC COMMIT         
TRANSACTION", conn);

    try
    {
        conn.Open();

        SqlDataReader dataReader = mySQL.ExecuteReader();

        string holderCountry = "";
        string holderScore = "";
        string holderYear = "";

        while (dataReader.Read())
        {
             holderCountry += dataReader["country"];
             holderScore += dataReader["score"];
             holderYear += dataReader["year"];
        }

        Console.WriteLine("\nCountry: "+holderCountry);
        Console.WriteLine("Score: " + holderScore);
        Console.WriteLine("Year: " + holderYear+"\n");

        conn.Close();
    }    
    catch (Exception e)
    {
        Console.WriteLine("Can not open connection ! ");
    }
}

下一段代码是给我一个错误的代码:

public static void showCountryAverage(string countryChoice)
        {
            string connetionString = "Data Source=DESKTOP-RV4VR9I;Initial 
Catalog=Assignment;User ID=Jake;Password=1234;Integrated Security=True";
            SqlConnection conn = new SqlConnection(connetionString);
            SqlCommand mySQL = new SqlCommand("BEGIN TRANSACTION SET 
TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT c.country, 
AVG(CAST(re.score AS DECIMAL(8, 6))) FROM main.country c JOIN 
main.restaurant r ON(c.countryId = r.countryId) JOIN main.review re 
ON(r.restaurantId = re.restaurantId) WHERE c.country = "+countryChoice+" 
GROUP BY c.country COMMIT TRANSACTION", conn);
            try
            {
                conn.Open();
                SqlDataReader dataReader = mySQL.ExecuteReader();
                string holderCountry = "";
                while (dataReader.Read())
                {

                    holderCountry += dataReader["country"];
                    holderCountry += dataReader["AVG(CAST(re.score AS     
DECIMAL(8, 6)))"];
                }
                Console.WriteLine("\nCountry: " + holderCountry);
                conn.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

谢谢!

这是错误

System.Data.SqlClient.SqlException (0x80131904):列名“意大利”无效。

在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection,Action1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
1 wrapCloseInAction)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔调用者HasConnectionLock,布尔异步关闭) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean & dataReady) 在 System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,字符串 resetOptionsString,布尔 isInternal,布尔 forDescribeParameterEncryption,布尔 shouldCacheForAlwaysEncrypted) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,布尔异步,Int32 超时,任务和任务,布尔异步写入,布尔 inRetry,SqlDataReader ds,布尔 describeParameterEncryptionRequest) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法,TaskCompletionSource`1 完成,Int32 超时,Task& 任务,Boolean& usedCache,Boolean asyncWrite,Boolean inRetry) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior 行为,字符串方法) 在 System.Data.SqlClient.SqlCommand.ExecuteReader() 在 C:\Users\User\Desktop\000SWD6.1B\2ndSemester\Database 2\Assignment\Database_Number_6\Database_Number_6\Program.cs:line 133 中的 Database_Number_6.Program.showCountryAverage(String countryChoice) ClientConnectionId:74fbcdc0-47ec-41cc-839d-0b05b13661df 错误号:207,状态:1,类:16

【问题讨论】:

  • 您是否阅读了错误信息?
  • 在某些 SELECT 查询中,BEGIN TRANSACTION 等的原因是什么?
  • @SLaks 这是一个很长的错误,但第一部分说“无效的列名”
  • @Steve 原因是它是一个任务,需要我们使用事务
  • 您需要为该列创建一个别名(使用as); SELECT 查询中的表达式不会成为列名。

标签: c# sql-server connection


【解决方案1】:

问题 Invalid column name Italy 是由您将字符串 Italy 连接到您的 sql 命令引起的。在 SQL 中,如果你想表达一个常量字符串值,你应该把它放在单引号之间,如 'Italy'。如果没有引号,sql 解析器引擎会认为您希望将 country 列中的值与 Italy 列中的值进行比较。因此,添加引号可以解决问题,但这是一个众所周知的解析错误来源(如果值包含自己的单引号怎么办?我什至不开始谈论日期)更糟糕的是,这种方法允许一种简单的方法通过Sql Injection 破解数据库。

创建需要代码值的查询的唯一正确方法是使用参数

SqlCommand mySQL = new SqlCommand(@".....
                                   SELECT c.country, 
                                   ....
                                   FROM main.country c 
                                   ....
                                   WHERE c.country = @country
                                   GROUP BY .....", con);
mySql.Parameters.Add("@country", SqlDbType.NVarChar).Value = countryCode;
 ....

【讨论】:

  • 谢谢史蒂夫!我刚刚修好了它,它与您的略有不同,尽管它几乎相同!再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多