1

I have the following code:

SqlCommand command = new SqlCommand(
    @"DECLARE @month int, @year int, @dateToCheck datetime;
      SET @month = @month;
      SET @year = @year;
      SET @dateToCheck = dateadd(month, 1, datefromparts(@year, @month, 1))

      SELECT p.name, dtc.cost_price, p.date_created
      FROM [dbo].[Company_Local_Invoice_] claidig
      JOIN Type_Company dtc on claidig.ID = dtc.id 
      WHERE p.date_created < @dateToCheck
      AND (p.date_left is null or p.date_left >= @dateToCheck)", conn);

command.Parameters.Add("@month", SqlDbType.Int).Value = month;
command.Parameters.Add("@year", SqlDbType.Int).Value = year;

The problem is that I can't seem to pass my SET parameters using command.Parameter.Add() .

The error that I get is:

The variable name '@month' has already been declared. Variable names must be unique within a query batch or stored procedure.

Why is this and how can I work around this?

3
  • You don't need to DECLARE anything when you make a query like that from ADO.Net. Just take out the DECLAREs and SETs and just add the Parameters. Commented Dec 1, 2018 at 13:25
  • but if i delete my dateToCheck from the query, my query will fail (or return bad results) Commented Dec 1, 2018 at 13:27
  • I would consider doing the date calculation in c#, but if you want to do it in SQL then just put that inline - replace ... >= @dateToCheck... with ... >= dateadd(month, 1, datefromparts(@year, @month, 1))... Commented Dec 1, 2018 at 13:29

2 Answers 2

3

The point Gordon is making is that when you pass parameters to a sql string, it prepends the 'declare' statements from the parameter definitions. So, you don't need to do the declare for anything that's coming in as parameters. You still need to declare any variable that gets computed from the parameters though.

var commandText = @"

  declare @dateToCheck datetime

  set @dateToCheck = dateadd(month, 1, datefromparts(@year, @month, 1))

  select 
    p.name, dtc.cost_price, p.date_created
  from 
    dbo.[Company_Local_Invoice_] claidig
    inner join 
    Type_Company dtc 
    on c
      laidig.ID = dtc.id 
  where
    p.date_created < @dateToCheck
    and 
    (
      p.date_left is null 
      or 
      p.date_left >= @dateToCheck
    )";

var command = new SqlCommand(commandText, conn);
command.Parameters.Add("@month", SqlDbType.Int).Value = month;
command.Parameters.Add("@year", SqlDbType.Int).Value = year;
Sign up to request clarification or add additional context in comments.

Comments

0

Just pass in the parameters and do the calculations in the query:

SELECT p.name, dtc.cost_price, p.date_created
FROM [dbo].[Company_Local_Invoice_] claidig
JOIN Type_Company dtc ON claidig.ID = dtc.id
CROSS APPLY (VALUES 
    (dateadd(month, 1, datefromparts(@year, @month, 1)))
) v(dateToCheck)
WHERE p.date_created < v.dateToCheck AND
      (p.date_left is null or p.date_left >= v.dateToCheck);

1 Comment

@user3127554 try adding one more closing paren ) before v(dateToCheck)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.