Is there a way to dynamically set a parameter in a stored procedure to the result of a query? - sql

I would like to be able to set a parameter of a stored procedure dynamically, based on the results of a SQL query. The stored procedure calculates the distance traveled between a particular date and today. That particular date could be different for each record in the database. (The date is calculated in a separate stored procedure.) See the example.
The stored procedure has two parameters: #DateFrom and #DateTo. #DateFrom should be the date in the DateFrom column, which, as you can see, is different for every record. Is there a way to loop through or something and set the #DateFrom parameter to the value in the DateFrom column for each record? #DateTo will always be today's date. Any help is greatly appreciated.

This is what I got from your question, it's my first answer to a post please excuses typos or code format
USE tempdb
GO
IF OBJECT_ID(N'Tempdb.dbo.#DataTest') IS NULL
BEGIN
CREATE TABLE #DataTest
(
ID INT IDENTITY
,Name VARCHAR(100)
,DateTo DATETIME
,DateFrom DATETIME
)
END
GO
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues1', '20151201',GETDATE() + 1)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues3', '20151203',GETDATE() + 2)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues5', '20151205',GETDATE() + 3)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues7', '20151207',GETDATE() + 4)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues9', '20151209',GETDATE() + 5)
GO
CREATE PROC #CalculateData
(
#DateTo DATETIME,
#DateFrom DATETIME
)
AS
SELECT DATEDIFF(SECOND,#DateTo,#DateFrom) AS DataResult
GO
DECLARE #Count INT = (SELECT MIN(ID) FROM #DataTest)
DECLARE #DateToParam DATETIME
DECLARE #DateFromToParam DATETIME
WHILE #Count IS NOT NULL
BEGIN
SET #DateToParam = (SELECT DateTo FROM #DataTest WHERE ID = #Count)
SET #DateFromToParam = (SELECT DateFrom FROM #DataTest WHERE ID = #Count)
EXEC #CalculateData #DateToParam, #DateFromToParam
SET #Count = (SELECT MIN(ID) FROM #DataTest WHERE ID > #Count)
END
GO
DROP TABLE #DataTest
DROP PROCEDURE #CalculateData

Related

How to run the query stored as a value in a row using Stored procedure for some condition

I have one table with 3 columns. One column captures the case no., one column captures all the DML (Insert / Update /Delete) query date wise for the specific case and one column captures the respective date and time at which the DML was performed. Now the row can repeat for a single case as it captures any DML performed for that case.
My requirement is that I have to write a procedure with Case No. and / or Date Time as a input parameter and after executing the procedure it must take all the DML query till the specific date and executes it as normal DML query.
Below is the sample table for the same:
For above case 1, I want to run all the dml statement for any specific date. Please help in this case.
Given the following schema and records:
create table caseLog
(
CaseID INT,
Query NVARCHAR(MAX),
[Date] DATETIME
);
CREATE TABLE Cases
(ID INT, Name NVARCHAR(50))
INSERT INTO caseLog (CaseID, Query, [Date])
VALUES
(1, 'INSERT INTO Cases (ID, Name) VALUES (1, ''First Name'')', '2019-04-02 15:00'),
(1, 'UPDATE Cases SET Name = ''Second Name'' WHERE ID = 1', '2019-04-02 16:00'),
(1, 'UPDATE Cases SET Name = ''Third Name'' WHERE ID = 1', '2019-04-02 17:00');
The procedure could look something like this:
CREATE PROCEDURE executeCaseLog
#CaseID INT,
#Until DATETIME
AS
DECLARE
#Query NVARCHAR(MAX) = '';
BEGIN
SELECT #Query += CONCAT(caseLog.Query, ';', CHAR(13), CHAR(10))
FROM caseLog
WHERE caseID = #CaseID
AND [Date] <= #Until
-- For showcase purposes
PRINT #Query
EXEC sp_executesql #Query
END;
GO
Now, if executed like so:
EXEC executeCaseLog #CaseID = 1, #Until = '2019-04-02 16:30'
It will yield the following:
SELECT * FROM Cases
ID Name
----------- --------------------------------------------------
1 Second Name
(1 row affected)

New to SQL - Why is my Insert into trying to insert NULL into primary key?

What I want to do is insert a range of dates into multiple rows for customerID=1. I have and insert for dbo.Customer(Dates), specifying my that I want to insert a record into the Dates column for my Customer table, right? I am getting error:
Cannot insert the value NULL into column 'CustomerId', table 'dbo.Customers'
Sorry if I am way off track here. I have looked at similar threads to find out what I am missing, but I'm not piecing this together. I am thinking it wants to overwrite the existing customer ID as NULL, but I am unsure why exactly since I'm specifying dbo.Customer(Dates) and not the existing customerID for that record.
declare #date_Start datetime = '03/01/2011'
declare #date_End datetime = '10/30/2011'
declare #date datetime = #date_Start
while #date <= #date_End
begin
insert into dbo.Customer(Dates) select #date
if DATEPART(dd,#date) = 0
set #date = DATEADD(dd, -1, DATEADD(mm,1,#date))
else
set #date = DATEADD(dd,1,#date)
end
select * from dbo.Customer
The primary key is customerId, but you are not inserting a value.
My guess is that you declared it as a primary key with something like this:
customerId int primary key,
You want it to be an identity column, so the database assigns a value:
customerId int identity(1, 1) primary key
Then, you don't need to assign a value into the column when you insert a new row -- the database does it for you.
Your Customer table has a column named CustomerId and which column is NOT Nullable so you have to provide that column value as well. If your column type is Int try the bellow code:
declare #date_Start datetime = '03/01/2011'
declare #date_End datetime = '10/30/2011'
declare #date datetime = #date_Start
DECLARE #cusId INT
SET #cusId = 1
while #date <= #date_End
begin
insert into dbo.Customer(CustomerId, Dates) select #cusId, #date
if DATEPART(dd,#date) = 0
set #date = DATEADD(dd, -1, DATEADD(mm,1,#date))
else
set #date = DATEADD(dd,1,#date)
SET #cusId = #cusId + 1;
end
select * from dbo.Customer
thank you for the feedback. I think I'm scrapping this and going to go with creating a separate table to JOIN. Not sure why I didn't start doing that before

How to update a table using while loops and waitfor delay to insert current date with a one second delay between records?

I'd like to create a table that contains two columns (id int, today datetime) and, using while loops, to insert the current date every 1 second. However, the resulting table shows the same time for all rows. Below is my code. Can anyone help me understand what I'm doing wrong, please? Thank you!
declare #mytable table (id int, today datetime)
declare #id int=1
declare #today datetime=getdate()
while #id<10
begin
waitfor delay '00:00:01'
insert into #mytable values (#id,#today)
set #id=#id+1
end
The reason every row has the same value is because you aren't setting the value of #Today anywhere apart from before your WHILE loop. GETDATE() returns a scalar value, and setting a variable to that value means it will be set the value that GETDATE() returned at the time the SET was run. The value of the variable won't change after time has passed. For example:
DECLARE #d datetime;
SET #d = GETDATE();
SELECT #d, GETDATE(); --Will return very similar values
WAITFOR DELAY '00:00:05';
SELECT #d, GETDATE(); --#d will have the same value as before, as its value is static, but GETDATE()'s value will have changed.
To do what you're after, I don't see any need for the variable for #Today, this would work fine:
DECLARE #mytable table (id int,
today datetime);
DECLARE #id int = 1;
WHILE #id < 10
BEGIN
WAITFOR DELAY '00:00:01';
INSERT INTO #mytable
VALUES (#id, GETDATE());
SET #id = #id + 1;
END;
However a loop is a bad choice anyway, as an RDBMS excels at set based operations, not iterative. You would be far better to achieve what you're after by doing:
DECLARE #mytable table (id int,
today datetime);
DECLARE #id int = 1;
WITH N AS (
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1
CROSS JOIN N N2 --Not actually eneded here, but shows how to increase row count
)
INSERT INTO #mytable (id,
today)
SELECT TOP 10
T.I + #ID,
DATEADD(SECOND, T.I, GETDATE())
FROM Tally T
ORDER BY T.I;
This builds an inline tally table, and then inserts a value for a row for 10 ID, and adds 1 second to each incremented ID.

Stored procedure in Microsoft SQL Server conversion before inserting

I am trying to create a stored procedure that does manipulation of parameter passed in before inserting it into my table. One of the columns in my table is called DATE_CHANGED and basically what I gg to do here is to change a passed date parameter like December 1st 2017 to 20171201. This is an int value.
I wrote a stored procedure like this:
CREATE PROCEDURE date_generate
#startDate DATE
AS
BEGIN
DECLARE #DATE_KEY INT
#DATE_KEY = CONVERT(INT, FORMAT(#startDate, 'YYYYMMDD')
INSERT INTO table date_key = #DATE_KEY
END
However I get an error
Incorrect syntax near '#DATE_KEY
Are local variable declared only used for SQL query statement like
select *
from table
where date_key = #DATE_Key?
There is more than one error.
Use SET to assign values to a variable.
Have a look at INSERT statement too.
CREATE PROCEDURE date_generate
#startDate date
AS
BEGIN
DECLARE #DATE_KEY int;
SET #DATE_KEY = CONVERT(int, format(#startDate, 'YYYYMMDD'));
INSERT INTO DATE_CHANGED (date_key)
VALUES (#DATE_KEY);
END
This seems really strange. You don't even need a local variable. Based on your code, you could write:
create procedure date_generate (
#startDate date
) as
begin
insert into table (date_key)
values ( convert(int, format(#startDate, 'YYYYMMDD')) );
end; -- date_generate
Or, I might write:
create procedure date_generate (
#startDate date
) as
begin
insert into table (date_key)
values ( year(#startDate) * 10000 + month(#startDate) * 100 + day(#startDate) );
end;
Why you would have a table with a single date on each row doesn't really make sense to me. Why you would be storing that "date" as an integer also doesn't make sense.
As far as I've understood, your stored procedure accepts a DATE as a parameter, but you need to do an INSERT with an INT.
You can easily convert a DATE to a VARCHAR and then to a INT, this way:
DECLARE #DateASInt INT = CAST(CONVERT(VARCHAR(8), #startDate, 112) AS INT);
So, your stored procedure will be like this:
CREATE PROCEDURE date_generate
#startDate date
AS
BEGIN
INSERT INTO date_key
VALUES (CAST(CONVERT(VARCHAR(8), #startDate, 112) AS INT));
END

Multiple parameters error while creating function in SQL Server

I created a function, now rather passing static value I want to add parameter in the function but after calling function it start throwing an error:
Procedure or function dbo.hello has too many arguments specified.
Function :
Create Function dbo.hello
(#InputstartDate Date, #InputendDate Date)
Returns #attendanceTemp table(STUD_NAME VARCHAR(50),
ATTD_DATE DATE ,
attd_DATEs DATE,
Attendance VARCHAR(20))
As
Begin
Declare #startDate DATE
SET #startDate = #InputstartDate
Declare #endDate Date
SET #endDate = #InputendDate
Declare #dateDifference INT
SET #dateDifference = DATEDIFF(day, #startDate,#endDate) ;
Declare #count INT
SET #count = 0
DECLARE #myTable TABLE (STUD_ID int,
countdd int,
STUD_NAME varchar(50),
AttDate Date
)
While #count <= #dateDifference
Begin
Insert Into #myTable (STUD_ID, countdd, STUD_NAME, AttDate)
Values (1, 123, 'HAIDER', #startDate)
Set #count = #count +1
Set #startDate = DATEADD(day, 1, #startDate)
End
Insert Into #attendanceTemp
Select
tb.STUD_NAME, ATTD_DATE, tb.AttDate,
Case
When att.DETAIL Is Null
Then 'ABSENT'
When att.DETAIL = 'ATTENDACE'
Then 'PRESENT'
End As Attendance
from
#myTable tb
Left Join
ATTENDANCE att on tb.AttDate = att.ATTD_DATE
Where
att.STUD_ID = 1 or att.STUD_ID IS NULL
Return
END
Calling the function:
select *
from dbo.hello('2014-04-01', '2014-04-10');
Error:
Procedure or function dbo.hello has too many arguments specified
Possibly you first created the function with only one parameter.
Then made changes to the 'create function' script, and forgot to deploy?
I would;
1. DROP FUNCTION dbo.hello
2. CREATE FUNCTION dbo.hello, with you script
3. Try executing your function again.
The function seems to work fine (Though I cannot run a full test due to not having table 'ATTENDANCE')