Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 添加字符串值时SQL Server列名无效_C#_Asp.net_Sql_Database_Web Services - Fatal编程技术网

C# 添加字符串值时SQL Server列名无效

C# 添加字符串值时SQL Server列名无效,c#,asp.net,sql,database,web-services,C#,Asp.net,Sql,Database,Web Services,我不熟悉SQL Server 我创建的表格如下所示: CREATE TABLE Accidents ( Id INT NOT NULL PRIMARY KEY IDENTITY, GUID VARCHAR(100), Latitude VARCHAR(100), Longitude VARCHAR(100), PhotoName VARCHAR(100) ) SqlConnection con = new Sq

我不熟悉SQL Server

我创建的表格如下所示:

CREATE TABLE Accidents (
     Id INT NOT NULL PRIMARY KEY IDENTITY,
     GUID VARCHAR(100),
     Latitude VARCHAR(100),
     Longitude VARCHAR(100),
     PhotoName VARCHAR(100)        
     )
    SqlConnection con = new SqlConnection(@"workstation id=DatabaseSample.mssql.somee.com;packet size=4096;user id=???;pwd=???;data source=DatabaseSample.mssql.somee.com;persist security info=False;initial catalog=DatabaseSample");

    public string addAccidentToDatabase(string GUID, string imageBase64String, string latitude, string longitude, string photoName)
    {
        SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES ("
            + GUID + "," + latitude + "," + longitude + "," + photoName + ")", con);

        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            return e.Message;
        }
        finally
        {
            con.Close();
        }

        return "succeeded";
    }
 p1.jpg'); DROP TABLE ACCIDENTS; -- 
我创建了一个web服务来向该表插入数据,如下所示:

CREATE TABLE Accidents (
     Id INT NOT NULL PRIMARY KEY IDENTITY,
     GUID VARCHAR(100),
     Latitude VARCHAR(100),
     Longitude VARCHAR(100),
     PhotoName VARCHAR(100)        
     )
    SqlConnection con = new SqlConnection(@"workstation id=DatabaseSample.mssql.somee.com;packet size=4096;user id=???;pwd=???;data source=DatabaseSample.mssql.somee.com;persist security info=False;initial catalog=DatabaseSample");

    public string addAccidentToDatabase(string GUID, string imageBase64String, string latitude, string longitude, string photoName)
    {
        SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES ("
            + GUID + "," + latitude + "," + longitude + "," + photoName + ")", con);

        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            return e.Message;
        }
        finally
        {
            con.Close();
        }

        return "succeeded";
    }
 p1.jpg'); DROP TABLE ACCIDENTS; -- 
所有这些东西都托管在一个免费的托管服务器上

当我从VS2010测试web服务时,当我将数字传递给所有参数时,一个新行成功地添加到表中。但是,当我向服务传递至少一个字符串时,例如“a”,我会得到以下结果:

<string xmlns="http://tempuri.org/">Invalid column name 'a'.</string>
列名称“a”无效。
并且不添加该行。我想知道他为什么认为“a”是一个列名?有人能帮忙吗

我想知道他为什么认为“a”是一个列名

这不难看出。你不应该开发软件,部署它并希望它运行。你应该测试一下。将正在执行的代码提取到类方法中,并从服务中调用该类方法。在开发时,您可以从单元测试或命令行程序或任何您喜欢使用的测试调用此方法

您的问题是:您没有在查询中的字符串(或varchar,如果需要)周围加引号。例如,如果您只是将查询字符串打印到控制台,您就会看到它

但老实说,这是你的最小问题。你不应该手工制作SQL。至少使用参数化查询。因此,让您的问题成为:

"INSERT INTO Accidents (GUID, Latitude, Longitude, PhotoName) 
                VALUES (@GUID, @Latitude, @Longitude, @PhotoName)"
并绑定参数:

cmd.Parameters.AddWithValue("@GUID", GUID);
...

字符串周围需要引号。您只是直接替换了这些值,所以SQL试图将它们解析为列

SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName)    
       VALUES ('" + GUID + "','" + latitude + "','" + longitude + "','" + photoName + "')", con);

但是,您应该注意,这是一个非常不安全的代码。它很容易被SQL注入。尝试改用参数化查询

我猜您的GUID值以
a
开头。如果它以
3
开头,你可能会得到一些更有趣的东西

由于您将其作为字符串传递,而不是使用引号转义,因此会收到一个错误

SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES ("
            + "\"" + GUID + "\"," + latitude + "," + longitude + ",\"" + photoName + "\")", con);
有几点:

  • 您应该真正避免以这种方式构建查询。使用存储过程或参数化查询

  • 为什么要将
    guid
    存储为
    varchar()
    ?有一个非常好的
    Guid
    数据类型可用

  • 不要以数据类型命名列


  • 您需要单引号来字符串值

    但我强烈建议您使用SQLParameters来避免任何
    SQLInjections
    攻击


    您可以找到使用

    的示例。请用此代码替换您的代码

     SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) " + 
                                     "VALUES (@guid, @lat, @long, @photo)", con);
     cmd.Parameters.AddWithValue("@guid", GUID);
     cmd.Parameters.AddWithValue("@lat", latitude);
     cmd.Parameters.AddWithValue("@long", longitude);
     cmd.Parameters.AddWithValue("@photo", photoName);
    
    为什么??好吧,假设您的一个字符串包含一个引号。
    查询将失败,并出现语法错误。但不要停下来听弦乐。日期和十进制数字呢?您需要以一种与数据库全球化设置相适应的方式对它们进行格式化,以便在具有不同设置的下一个客户上失败。参数将为您解决此问题

    最差的。假设恶意用户在PhotoName的输入框中键入如下内容:

    CREATE TABLE Accidents (
         Id INT NOT NULL PRIMARY KEY IDENTITY,
         GUID VARCHAR(100),
         Latitude VARCHAR(100),
         Longitude VARCHAR(100),
         PhotoName VARCHAR(100)        
         )
    
        SqlConnection con = new SqlConnection(@"workstation id=DatabaseSample.mssql.somee.com;packet size=4096;user id=???;pwd=???;data source=DatabaseSample.mssql.somee.com;persist security info=False;initial catalog=DatabaseSample");
    
        public string addAccidentToDatabase(string GUID, string imageBase64String, string latitude, string longitude, string photoName)
        {
            SqlCommand cmd = new SqlCommand("INSERT INTO Accidents (GUID,Latitude,Longitude,PhotoName) VALUES ("
                + GUID + "," + latitude + "," + longitude + "," + photoName + ")", con);
    
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                return e.Message;
            }
            finally
            {
                con.Close();
            }
    
            return "succeeded";
        }
    
     p1.jpg'); DROP TABLE ACCIDENTS; -- 
    

    这是一个很大很大的问题——它被称为,是的,一个参数阻止了这一点。我真的希望您不要在有敏感信息的数据库上编写此代码。

    谢谢链接。我必须更加小心。谢谢你解决了这个问题。为什么要投反对票?我只是问:)+1来抵消愚蠢的否决票。伙计们,我以为这是一个人们可以问问题的地方?反对票的警察通常要到星期一早上才出来您应该始终使用最合适的数据类型——毕竟,这就是它们的用途!因此列
    GUID
    应该是
    UNIQUEIDENTIFIER
    类型,像
    经度
    纬度
    这样的数值应该是
    十进制(16,4)
    或类似的-而不是
    varchar(100)
    @marc_s,谢谢你的评论。如果OP不难看到,我怀疑会有人问这个问题。回答得很好,但有点居高临下。