3

I want update in my table if my given filename is already in my database else I want to insert a new row. I try this code but the EXISTS shown error please give me the correct way beacuse iam fresher in SQL

public void SaveData(string filename, string jsonobject)
{
    SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=;Integrated Security=True");
    SqlCommand cmd;
    SqlCommand cmda;

    if EXISTS("SELECT * FROM T_Pages WHERE pagename = '" + filename + "") {
        cmda = new SqlCommand("UPDATE T_Pages SET pagename='" + filename + "',pageinfo='" + jsonobject + "' WHERE pagename='" + filename + "'", con);
        cmda.ExecuteNonQuery();
    }
    else {
        cmd = new SqlCommand("insert into T_Pages (pagename,pageinfo) values('" + filename + "','" + jsonobject + "')", con);
        cmd.ExecuteNonQuery();
    }

    con.Close();
}
peak
  • 105,803
  • 17
  • 152
  • 177
Manu Padmanabhan
  • 555
  • 1
  • 4
  • 16
  • What is `if EXISTS` ? you're in C# code. you can't write SQL syntax in C# code – Royi Namir Aug 31 '16 at 12:33
  • Did you define/implement EXIST function? you need to. – Sami Aug 31 '16 at 12:33
  • 2
    `MERGE` is for this purpose – Maheswaran Ravisankar Aug 31 '16 at 12:33
  • @MaheswaranRavisankar Too complicated.....:-) I don't trust it – Royi Namir Aug 31 '16 at 12:34
  • 1
    MERGE is a poor choice here, use IF EXISTS/INSERT/UPDATE in a single batch. – Alex K. Aug 31 '16 at 12:34
  • Hello please see this [LINK](http://stackoverflow.com/a/17903139/5330851) I think you will find it useful. – Bogoljub Aug 31 '16 at 12:34
  • Did you see the first two comments? Your code won't even compile if `EXISTS` is not implemented somewhere so I'm going to guess, at minimum, you must apply the closing single quote around `filename` in the `if` statement. – Crowcoder Aug 31 '16 at 12:37
  • 2
    [SQL Injection alert](http://msdn.microsoft.com/en-us/library/ms161953%28v=sql.105%29.aspx) - you should **not** concatenate together your SQL statements - use **parametrized queries** instead to avoid SQL injection – marc_s Aug 31 '16 at 12:47

5 Answers5

24

You should

  • use parameters in your query - ALWAYS! - no exception
  • create a single query that handles the IF EXISTS() part on the server
  • use the generally accepted ADO.NET best practices of putting things into using() {....} blocks etc.

Try this code:

public void SaveData(string filename, string jsonobject)
{
    // define connection string and query
    string connectionString = "Data Source=.;Initial Catalog=;Integrated Security=True";
    string query = @"IF EXISTS(SELECT * FROM dbo.T_Pages WHERE pagename = @pagename)
                        UPDATE dbo.T_Pages 
                        SET pageinfo = @PageInfo
                        WHERE pagename = @pagename
                    ELSE
                        INSERT INTO dbo.T_Pages(PageName, PageInfo) VALUES(@PageName, @PageInfo);";

    // create connection and command in "using" blocks
    using (SqlConnection conn = new SqlConnection(connectionString))
    using (SqlCommand cmd = new SqlCommand(query, conn))
    {
        // define the parameters - not sure just how large those 
        // string lengths need to be - use whatever is defined in the
        // database table here!
        cmd.Parameters.Add("@PageName", SqlDbType.VarChar, 100).Value = filename;
        cmd.Parameters.Add("@PageInfo", SqlDbType.VarChar, 200).Value = jsonobject;

        // open connection, execute query, close connection
        conn.Open();
        int rowsAffected = cmd.ExecuteNonQuery();
        conn.Close();
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
5

How about using one MERGE statement?
Of course with parameters to avoid a risk of SQL injection.

public void SaveData(string filename, string jsonobject)
{
  SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=;Integrated Security=True");

  SqlCommand cmd;

  cmd = new SqlCommand(@"
    MERGE T_Pages AS target  
    USING (SELECT @PageName as pagename, @PageInfo as pageinfo) AS source 
    ON (target.pagename = source.pagename)  
    WHEN MATCHED THEN   
        UPDATE SET pageinfo = source.pageinfo  
    WHEN NOT MATCHED THEN  
    INSERT (pagename, pageinfo)  
    VALUES (source.pagename, source.pageinfo)", con);

   cmd.Parameters.Add(new SqlParameter("@PageName", filename));
   cmd.Parameters.Add(new SqlParameter("@PageInfo", jsonobject));

   con.Open();
   cmd.ExecuteNonQuery();
   con.Close();
 }
LukStorms
  • 28,916
  • 5
  • 31
  • 45
  • Yes, MERGE should be perfect in this case. Depending on the SQL Server Version. I believe it was introduced in SQL 2008 only... – Antonio Aug 31 '16 at 14:38
  • Indeed, [MERGE](https://msdn.microsoft.com/en-us/library/bb510625.aspx) was introduced in the 2008 version. Based on the SQL:2003 standard. Since the question didn't specify the DB version one can't assume that it has to work on SQL Server 2005 or earlier :) – LukStorms Aug 31 '16 at 14:59
1

Create a Stored procedure on the database along the lines of

CREATE PROCEDURE T_Pages_Write  (@pagename nvarchar(256) ,@pageinfo nvarchar(max)) 
AS
IF EXISTS (SELECT pagename from T_Pages WHERE pagename = @pagename)
UPDATE T_Pages SET pageinfo = @pageinfo WHERE pagename = @pagename
ELSE 
INSERT T_Pages (pagename, Pageinfo) VALUES (@pagename, @Pageinfo)

And call that from your code. You really should do that with a parameterised command (There will be loads of other questions advising you on the best way to do that). If you're willing to run the risk of SQL injection attacks and don't mind it failing if there's a single quote character in your data then you can do it the quick and dirty way like this

cmd = new SqlCommand("EXEC T_PagesWrite @pagename = '" + filename + "', @pageinfo ='" + jsonobject + "'", con);
Tom Page
  • 1,211
  • 1
  • 7
  • 8
0

You can done this with one Query

where you want to decalre flag variable of type int ( you also make it of type tinyint, it's up to you) and if the count is 0, means no rows ,else you update your Query

SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=;Integrated Security=True");
SqlCommand cmd;
cmda = new SqlCommand("declare @flag int ;set @flag = 0;select @flag = COUNT(*) FROM T_Pages WHERE pagename = '" + filename + "';IF @flag = 1 UPDATE T_Pages SET pagename='" + filename + "',pageinfo='" + jsonobject + "' WHERE pagename='" + filename + "';ELSE insert into T_Pages (pagename,pageinfo) values('" + filename + "','" + jsonobject + "');", con);
cmda.ExecuteNonQuery();
con.Close();
Faraz Ahmed
  • 1,467
  • 2
  • 18
  • 33
  • why .some one down vote this answer ..? according to the question pattern (if don't think about the sql injection ...somthing ....) this code is working one . – Manu Padmanabhan Sep 01 '16 at 02:06
  • 1
    @mr.cool , you are right, but what we can do? here are some members they think ,they are right, as we see that person who ask question has no background of sql injection from his question, but still second time StackOverflow break my heart. :( – Faraz Ahmed Sep 01 '16 at 05:08
  • 1
    but i done up vote because as a fresher this code is more understandable one – Manu Padmanabhan Sep 01 '16 at 06:20
-1
public void SaveData(string filename, string jsonobject)
    {
        SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=;Integrated Security=True");
        SqlCommand cmd;
        SqlCommand cmda;

        SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM T_Pages WHERE pagename = '" + filename + "", con);
        DataSet ds = new DataSet();
        da.Fill(ds);



        if (ds.Tables[0].Rows.Count > 0)
        {

            cmda = new SqlCommand("UPDATE T_Pages SET pagename='" + filename + "',pageinfo='" + jsonobject + "' WHERE pagename='" + filename + "'", con);
            cmda.ExecuteNonQuery();
        }
        else
        {
            cmd = new SqlCommand("insert into T_Pages (pagename,pageinfo) values('" + filename + "','" + jsonobject + "')", con);
            cmd.ExecuteNonQuery();
        }


        con.Close();



    }
Hitesh Thakor
  • 471
  • 2
  • 12