SQL Server : Procedure, setting value for the variables [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Intending to update Table6 with the following procedure. I have set variables and they are correctly addressed but how do I define value for the 2 types of variables. there are search variables and update variables
Procedure with condition if the cell has NULL value than add whatever the Variable has but if it already has value then leave its original value/don't overwrite it.
CREATE PROCEDURE dbo.[Learning]
#StartDate DATE NULL,
#EndDate DATE NULL,
#Data VARCHAR(30) NULL,
#Cond_CID INT NOT NULL,
#Cond_PID INT NOT NULL,
#Cond_SSC VARCHAR(3) NOT NULL
AS
BEGIN
BEGIN
UPDATE temp.dbo.Table6
SET StartDate = ISNULL(StartDate,#StartDate)
,EndDate = ISNULL(EndDate,#EndDate)
,Data = ISNULL(Data,#Data)
WHERE Table6.CID = #Cond_CID AND TABLE6.PID = #Cond_PID AND TABLE6.SSC = #Cond_SSc
The table and data insert
CREATE TABLE temp.dbo.Table6
(
CID INT NOT NULL,
PID INT NOT NULL,
SSC VARCHAR(3) NULL,
StartDate DATE NULL,
EndDate DATE NULL,
Data VARCHAR(30) NULL
)
INSERT INTO temp.dbo.Table6
VALUES
(1001, 1333,'OP', GETDATE(), GETDATE(), 'OP2001156519952012'),
(1002, 1245,'OR', GETDATE(), NULL, 'OR20121005'),
(1003, 1116,'OP', GETDATE(), NULL, 'OP20131215'),
(1004, 1234,'OP', GETDATE(), GETDATE(), 'OP2001156519952012')
SELECT * FROM temp.dbo.Table6
sample data which has null values and this procedure will be used to populate data into the table.

It seems like you want to prevent the (3) search parameters to be NULLs, but when you set those parameters as NOT NULL SQL Server will complain about it, and throw
Msg 11555 Level 15 State 1 Line 7
The parameter 'ParameterName' has been declared as NOT NULL. NOT NULL parameters are only supported with natively compiled modules, except for inline table-valued functions.
Also, I think your first 3 parameters shouldn't be NULL too, cause if you pass NULLs then your UPDATE won't do anything, just set your columns to NULL again.
You can check for NULLs in the body of your SP, and if one of them IS NULL then raise an error as
CREATE PROCEDURE dbo.[Learning]
(
#StartDate DATE,
#EndDate DATE,
#Data VARCHAR(30),
#Cond_CID INT,
#Cond_PID INT,
#Cond_SSC VARCHAR(3)
)
AS
BEGIN
IF (#Cond_CID IS NULL OR #Cond_PID IS NULL OR #Cond_SSC IS NULL
OR #StartDate IS NULL OR #EndDate IS NULL OR #Data IS NULL
)
BEGIN
RAISERROR('Null values not allowed for the 3 last parameters!', 16, 1)
END
ELSE
BEGIN
UPDATE temp.dbo.Table6
SET StartDate = ISNULL(StartDate,#StartDate)
,EndDate = ISNULL(EndDate,#EndDate)
,Data = ISNULL(Data,#Data)
WHERE Table6.CID = #Cond_CID
AND
TABLE6.PID = #Cond_PID
AND
TABLE6.SSC = #Cond_SSc
END
END
or by Creating Natively Compiled Stored Procedures.

Related

SQL Update Based on Subquery

I am having trouble coming up with this SQL statement to go and update certain records that already exist. For the sake of brevity, I am using hard coded values.
What I want to do is the following:
When there is already a record within the PersonXNotifyUser table where the UserID and NotifyUserID match, I want to make sure that I update the IsDeleted column to a value of 0, and also update the ModifiedBy and ModifiedDate columns accordingly. Here is what I have so far, which doesn't execute, but am hoping someone can help me out:
UPDATE: Since one of the answers assumed there is need for a subquery, I have added the Table Type and the stored procedure definition which expects the Table Valued Parameter
CREATE TYPE dbo.GuidIDList
AS TABLE
(
ID [UNIQUEIDENTIFIER]
);
CREATE PROCEDURE [dbo].[PersonXNotifyUser_InsertUpdate]
(
,#UserID [UNIQUEIDENTIFIER]
,#NotifyUserIDs AS dbo.GuidIDList READONLY
,#EditingUserID [UNIQUEIDENTIFIER]
)
AS
SET NOCOUNT ON
UPDATE PersonXNotifyUser
SET IsDeleted = 0, ModifiedBy = #EditingUserID, ModifyDate = GETUTCDATE()
FROM (
SELECT
test.NotifyUserID
FROM (
SELECT ID FROM #NotifyUserIDs
)
AS test (NotifyUserID)
WHERE EXISTS
(SELECT PersonXNotifyUserID
FROM PersonXNotifyUser pnu
WHERE pnu.UserID = #UserID AND pnu.NotifyUserID = test.NotifyUserID
)
)
Based on the inputs given in the question, it does not seems like you need a join or subquery for achieving this. Use a Simple Update
DECLARE #UserID UNIQUEIDENTIFIER = '45D9F7E4-E111-4E62-8B1A-118F7C7FB6A1'
DECLARE #EditingUserID UNIQUEIDENTIFIER = 'CDFDBD9A-87FB-4F68-B695-F4A39424C207'
UPDATE PersonXNotifyUser
SET
IsDeleted = 0,
ModifiedBy = #EditingUserID,
ModifyDate = GETUTCDATE()
WHERE UserID = #UserID
AND EXISTS
(
SELECT
1
FROM #NotifyUserIDs
WHERE ID = PersonXNotifyUser.NotifyUserID
)

Provide endDate to previous value

I want to provide an EndDate when the MainAccountNum already exist. The endDate should be applied to the MainAccountNumb with the earliest startDate.
So If I have a create table statement like this:
Create Table ods.CustomerId(
ScreenDate INT NOT NULL,
CustomerNum nvarchar(40) NOT NULL,
MainAccountNum nvarchar(40) not null,
ServiceNum nvarchar(40) not null,
StartDate datetime not null,
EndDate datetime not null,
UpdatedBy nvarchar(50) not null);
and say I encounter something in the CustomerNum, MainAccountNum, StartDate, and EndDate like below:
1467823,47382906,2019-08-26 00:00:00.000, Null
1467833,47382906,2019-09-06 00:00:00.000, null
When the second record is inserted with that same MainAccountNum the first record should get the startDate of the New Record. The startDate has a default constraint as GetDat() so in the end it should look like:
1467823,47382906,2019-08-26 00:00:00.000,2019-09-06 00:00:00.000
1467833,47382906,2019-09-06 00:00:00.000, null
Please Provide code examples of how this can be accomplished
In the stored procedure used to insert new record, have something like
begin tran
declare #startDate datetime
select top 1 #oldStartDate = StartDate
from ods.CustomerId
where MainAccountNum = #mainAccountNum
order by StartDate asc
if ##rowcount > 0
update ods.CustomerId set EndDate = #startDate
where MainAccountNum = #mainAccountNum and StartDate = #oldStartDate
insert ... <your new record here>
commit
I am assuming that (MainAccountNum, StartDate) tuple is unique and can be used as a key. If not, you have to use whatever is unique for your update statement.

Using the identity column to add a value to a computed column

At times I need to store a temporary value to a field. I have a stored procedure that adds it using:
Insert new record first then
SELECT #Record_Value = SCOPE_IDENTITY();
UPDATE ADMIN_Publication_JSON
SET NonPubID = CAST(#Record_Value as nvarchar(20)) + '_tmp'
WHERE RecID = #Record_Value
It simply takes the identity value and adds an '_tmp' to the end. Is there a way that I can create a default value in the table that would do that automatically if I did not insert a value into that field?
The NonPubID column is just a NVARCHAR(50).
Thanks
You could write a trigger, that replaces NULL with that string upon INSERT.
CREATE TRIGGER admin_publication_json_bi
ON admin_publication_json
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE apj
SET apj.nonpubid = concat(convert(varchar(20), i.id), '_tmp')
FROM admin_publication_json apj
INNER JOIN inserted i
ON i.id = apj.id
WHERE i.nonpubid IS NULL;
END;
db<>fiddle
Downside: You cannot explicitly insert NULLs for that column, should that be desired.
Check out NewKey col below:
CREATE TABLE #Table
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
IDValue VARCHAR(1) ,
ModifiedDT DATETIME NULL,
NewKey AS ( CONVERT(VARCHAR(100),ID)+'_Tmp' )
)
INSERT #Table( IDValue, ModifiedDT )
SELECT 'A', GETDATE()
UNION ALL
SELECT 'Y', GETDATE() - 1
UNION ALL
SELECT 'N', GETDATE() - 5
SELECT * FROM #Table

Declare multiple variables in SQL

I am new to SQL and trying to determine how to set a variable to either A or B.
Here is the statement:
DECLARE #Planner AS VARCHAR(50) = '2566927' OR #Planner = '12201704'
And the error I am receiving:
The following errors occurred during execution of the SQL query:
Incorrect syntax near the keyword 'OR'.
Here is a more complete sample:
DECLARE
#Planner AS VARCHAR(50) = '2566927'
--Temp Table for Final
CREATE TABLE #PP1(
Part_Key varChar(50)
,Part_No varChar(50)
,Part_Name varChar(50)
,CurInv DECIMAL(10,2)
,MinInv DECIMAL(10,2)
,Past_Due DECIMAL(10,2)
,Week2 DECIMAL(10,2)
,Week4 DECIMAL(10,2)
,Week8 DECIMAL(10,2)
,Week12 DECIMAL(10,2)
,Plus12 DECIMAL(10,2)
,Dep26w DECIMAL(10,1)
,Stock DECIMAL(10,1)
,StockPur DECIMAL (10,1)
)
--Temp Table to Limit Parts
CREATE TABLE #MRP_Parts(
MRP_PK varChar(50)
,MRP_PN varChar(50)
,MRP_PNAME varChar(50)
)
--Insert into Temp Part Table
INSERT #MRP_Parts
SELECT
PP.Part_Key
,PP.Part_No
,PP.Name
FROM Part_v_Part AS PP
WHERE (PP.Planner = #Planner OR #Planner = '')
--BEGIN Temp Table for Inventory
CREATE TABLE #CurrInv(
CI_Part_Key varChar(50)
,CI_Part_No varChar(50)
,CI_Qty DECIMAL(10,1)
,CI_Min DECIMAL(10,2)
)
INSERT #CurrInv
SELECT
PP.PArt_Key
,PP.Part_No
,ISNULL(PC1.Quantity,0)
,PP.Minimum_Inventory_Quantity
FROM Part_v_Part AS PP
OUTER APPLY
(
SELECT
SUM(PC.Quantity) AS Quantity
FROM Part_v_Container as PC
WHERE PP.part_Key=PC.part_Key
AND (PC.Container_Status = 'OK'
OR PC.Container_Status = 'Receiving'
OR PC.Container_Status = 'Testing Hold')
AND PC.Active = '1'
AND (PP.Planner = #Planner OR #Planner = '')
) AS PC1
What I would like is for the #Planner to be either A or B
A second variable must have a different name. E.g.
DECLARE #Planner1 VARCHAR(50) = '2566927',
#Planner2 varchar(10) = '12201704',
#OtherVar int = 42
And separate each variable declaration with a comma ,
You can't do that, but you can declare a variable as a table and put multiple values into the table
DECLARE #Planner AS TABLE (P VARCHAR(50))
INSERT #Planner SELECT '2566927'
INSERT #Planner SELECT '12201704'
And then you can use the table variable in a where in type clause
SELECT
PP.Part_Key
,PP.Part_No
,PP.Name
FROM Part_v_Part AS PP
WHERE PP.Planner IN (SELECT P FROM #Planner)

Get SQL Insert to work when PK is supplied or NOT

I have the following stored procedure:
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
-- If #ServerEnvironmentId was not supplied.
IF (#ServerEnvironmentId IS NULL)
BEGIN
-- Get the ServerEnvironmentId.
SELECT #ServerEnvironmentId = ServerEnvironmentId
FROM #APPL_ServerEnvironment
END
The ServerEnvironmentId column is a primary key with a default set on it, which is (newsequentialid()).
I need this stored procedure to work for 2 scenarios:
Value supplied for ServerEnvironmentId - WORKS.
Value not supplied for ServerEnvironmentId - DOES NOT WORK - CANNOT INSERT NULL VALUE. I thought by setting a default on this column this would be fine.
Someone please help to ammend this procedure so that it may work for both scenarios. Solution needs to have minimal changes as all sp's currently following this trend.
Default values are only applied on inserts if the column is not included in the INSERT list. I'd recommend the following not entirely trivial change (I've commented out the lines to be removed):
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
---- Stores the ServerEnvironmentId.
--DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
IF #ServerEnvironmentName is null
SET #ServerEnvironmentName = newid()
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
--OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
---- If #ServerEnvironmentId was not supplied.
--IF (#ServerEnvironmentId IS NULL)
--BEGIN
-- -- Get the ServerEnvironmentId.
-- SELECT #ServerEnvironmentId = ServerEnvironmentId
-- FROM #APPL_ServerEnvironment
--END
The default constraint will not be used by this procedure, but you can leave it in place if there are other places where rows may be added to the table.
(My first answer was long and so it this one, so I'm posting a second answer.)
I missed that you were using NewSequentialId. Again, if a column is specified within the insert statement, any DEFAULT values assigned to that column will not be used [unless you use the DEFAULT keyword in the INSERT statement, but that's still all or nothing--you can't say "if #Var is null then DEFAULT"]. I think you are stuck with simple branching and semi-redundant code, along the lines of:
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
IF #ServerEnvironmentId is null
BEGIN
-- ServerEnvironmentId not provided by user, generate during the insert
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
-- Get the new ServerEnvironmentId
SELECT #ServerEnvironmentId = ServerEnvironmentId
FROM #APPL_ServerEnvironment
END
ELSE
BEGIN
-- ServerEnvironmentId is provided by user
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId,
ServerEnvironmentId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId,
#ServerEnvironmentId
)
END
(Why lock the entire table during the insert?)
Help to Simplify SQL Insert which uses NEWSEQUNETIALID() column default