Jordan Moffat
Jordan Moffat

Reputation: 337

SQL Insert/ Counter Increment

I'm trying to make a program that allows me to store trends in an SQL Table. I need to add a hashtag entered into a textbox into the database if it doesn't already exist, and then increment a counter by 1.

The first column is "HashTag" and the second is "Counter" which has char(10) and int properties respectively.

I'm new to SQL, so it's posing a bit of a problem. This is what I have so far.

SqlConnection connection = new SqlConnection();
connection.ConnectionString = (@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Jordan Moffat\Desktop\coursework\WindowsFormsApplication\WindowsFormsApplication\HashTags.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
connection.Open();
HashTagReader r = new HashTagReader();
if (r.HashTagSearch(s))
    MessageBox.Show("I Found it!");
else
{
    SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag, Counter) " + "Values (s, ++)", connection);
    myCommand.ExecuteNonQuery();
}
connection.Close();

Any suggestions?

Upvotes: 1

Views: 1053

Answers (4)

Ben Thul
Ben Thul

Reputation: 32687

If you're on SQL 2008+, you have access to the merge statement. Something like so:

CREATE TABLE #tmp
    (
      [HashTag] VARCHAR(10) NOT NULL ,
      [Counter] INT NOT NULL
    );

MERGE [#tmp] AS t
    USING 
        (
          SELECT    [HashTag] ,
                    [Counter]
          FROM      ( VALUES ( '#kitties', 3) ) AS f ( [HashTag], [Counter] )
        ) AS s
    ON t.[HashTag] = s.[HashTag]
    WHEN NOT MATCHED BY TARGET 
        THEN
    INSERT  ( [HashTag], [Counter] )
          VALUES
            ( s.[HashTag] ,
              s.[Counter]
            )
    WHEN MATCHED 
        THEN
    UPDATE
          SET
            t.[Counter] += s.[Counter]
    OUTPUT
        $ACTION ,
        INSERTED.* ,
        DELETED.*;

I'm using an output clause here just so that it says what it's doing. Execute the merge statement multiple times and see how the output changes. If you're feeling frisky, wrap this in a stored procedure that takes two parameters (hashtag and counter) and you've got yourself something nice. Enjoy!

Upvotes: 1

BizApps
BizApps

Reputation: 6130

You can use Parameters to avoid sql injection :

   string hashtag = "Your HashTagValue";
   string counter = "Your Counter Value";

   SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag, Counter) Values (@HashTag,@Counter)", connection);
   myCommand.Parameters.Add("@HashTag", SqlDbType.varchar,50).Value = hashtag;  //Your hashTagvalue
   myCommand.Parameters.Add("@Counter", SqlDbType.varchar,50).Value = counter; //Your Counter Value

   myCommand.ExecuteNonQuery();

Upvotes: 0

Chris Gessler
Chris Gessler

Reputation: 23113

Change the Counter column to Identity(1,1) and it will auto increment. You can easily do this through SQL Management Studio.

Then change your query to:

SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag) Values ('" + s + '")", connection); 

Note: I believe SqlCommand inherits from DbCommand which implements IDisposable. You should wrap these objects with a using() statement, like so to clean up any unmanaged resources:

using(SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag) Values ('" + s + '")", connection))
{
  ...
}

Upvotes: 1

Parker
Parker

Reputation: 1102

To add to Chris' answer, to avoid duplicate inserts you should (if you 're on SQL Server 2005 or higher) add a unique index to the HashTag column to enforce the restriction.

Then in the code you should use a WHERE NOT EXISTS clause. See here: SQL Server insert if not exists best practice

So you'd wind up with:

"INSERT INTO tblHashTag (HashTag)
             Values ('" + s + "')
 WHERE NOT EXISTS (SELECT HashTag 
                   FROM tblHashTag
                   WHERE HashTag = '" + s + '")"

Upvotes: 0

Related Questions