A simple query in stored procedure - sql

Need to make a stored procedure that will do a simple search on a table, plus have 3 parameters, the first two are a date range, the third is if different from NULL will be included in the WHERE, if equal to NULL then not seek that value, as I can do this search?

Where #parameter1 = ColA
AND #parameter2 = ColB
and ISNULL(#parameter3, ColC) = ColC

try this..
Create Prucedure test
#p1 int,#p2 int,#p3 nvarchar(50)
As
Begin
If #p3 is null
Select * from table where field1=#p1 and field2=#p2
Else
Select * from table where field1=#p1 and field2=#p2 and field3=#p3
End
Sorry for improper formatting this is because i am sending the answer from a cell phone

WHERE #parameter IS NULL or field = #parameter

Yes! you can do that by passing the three variables to the host program and write a customized CURSOR SELECT using them. Then open the cursor and throw the resultset. Your search results are now ready to use. If needed syntactical help, revert with the host language and specifications you are using. Do post the challenges and solution you got for the same, may help others.

Try the following. Note that if Column3 could be null then you need to use the isnull() function on the column name as well as you can't compare null values. So if the data type of Column3 is int then you could use: and isnull(Column3, 0) = isnull(#param3, isnull(Column3, 0)).
create procedure Test
#param1 varchar(50),
#param2 varchar(50),
#param3 varchar(50) = null
as
begin
select *
from Table1
where Column1 = #param1
and Column2 = #param2
and Column3 = isnull(#param3, Column3)
end

The general form of what you are attempting to perform is a dynamic query. See the solution in this problem update statement not executing

I am using the adventure works database.
CREATE PROCEDURE upContactDetails
#FirstName [nvarchar](50),
#LastName [nvarchar](50),
#MiddleName [nvarchar](50)
AS
BEGIN
SET NOCOUNT ON;
SELECT Title
, FirstName
, MiddleName
, LastName
, EmailAddress
FROM Person.Contact
WHERE (#MiddleName IS NULL or MiddleName = #MiddleName)
AND FirstName = #FirstName
AND LastName = #LastName
END
GO

Imagine that You're having a transaction table where you store transaction Number And Transaction Date as shown Below.
CREATE TABLE [dbo].[TrnMast](
[TrnNo] [numeric](10, 0) NOT NULL,
[AcYear] [int] NOT NULL,
[Comp_Code] [varchar](5) NOT NULL,
[InvNo] [varchar](20) NULL,
[TrnDate] [datetime] NULL,
[P_Code] [varchar](5) NULL,
[Amount] [money] NULL,
[Remark] [varchar](50) NULL
CONSTRAINT [PK_TrnMast_1] PRIMARY KEY CLUSTERED
(
[TrnNo] ASC,
[Comp_Code] ASC,
[AcYear] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Now Look at stored procedure with 3 parameters having two date range paramaters and TrnNo Below.
CREATE PROCEDURE [dbo].[SP_TrnMast]
#FTrnDate SmallDateTime = Null,
#TTrnDate SmallDateTime = Null,
#AcYear Int
AS
Begin
Select * From TrnMast
Where (#FTrnDate Is Null Or TrnMast.TrnDate >= #FTrnDate)
And (#TTrnDate Is Null Or TrnMast.TrnDate <= #TTrnDate)
And TrnMast.AcYear = #AcYear
End

Related

Trying to write a stored procedure with a Identity column to create my table values

I am trying to write a stored procedure that creates a new row of data in my table that has an Identity column. I can't figure out what I'm doing wrong to get it to store my data in the table.
Here is my table
CREATE TABLE [Promotional].[Proposals]
(
[Proposal_Uid] [int] IDENTITY(1,1) NOT NULL,
[Prime_Contract] [nvarchar](30) NULL,
[Sub_Contract] [nvarchar](30) NULL,
[Po_Id] [nvarchar](30) NULL,
[Proposal_Title] [nvarchar](50) NULL,
[Client_Name] [nvarchar](40) NULL,
[Client_Code] [nvarchar](20) NULL,
[Total_Proposal_Amount] [decimal](18, 2) NULL,
[ODC_Amount] [decimal](18, 2) NULL,
[Manager_Name] [nvarchar](30) NULL,
[Admin] [nvarchar](30) NULL,
[Due_Date] [date] NULL,
[Start_Date] [date] NULL,
[End_Date] [date] NULL,
[Proposal_Number] [nvarchar](20) NULL,
[Contract_Type] [nvarchar](16) NULL,
CONSTRAINT [Proposal_Uid]
PRIMARY KEY CLUSTERED ([Proposal_Uid] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Here is my stored procedure:
ALTER PROCEDURE [Promotional].[Proposals_Create]
(#Prime_Contract nvarchar(30),
#Sub_Contract nvarchar(30),
#Po_Id nvarchar(30),
#Proposal_Title nvarchar(50),
#Client_Name nvarchar(40),
#Client_Code nvarchar(20),
#Total_Proposal_Amount decimal(18,2),
#ODC_Amount decimal(18,2),
#Manager_Name nvarchar(30),
#Admin nvarchar(30),
#Due_Date date,
#Start_Date date,
#End_Date date,
#Proposal_Number nvarchar(20),
#Contract_Type nvarchar(16),
#NewId int output)
AS
BEGIN
IF #NewId IS NULL
BEGIN
INSERT INTO Promotional.Proposals (Prime_Contract, Sub_Contract, Po_Id, Proposal_Title, Client_Name, Client_Code,
Total_Proposal_Amount, ODC_Amount, Manager_Name, Admin, Due_Date, Start_Date, End_Date, Proposal_Number, Contract_Type)
VALUES (#Prime_Contract, #Sub_Contract, #Po_Id, #Proposal_Number, #Client_Name, #Client_Code,
#Total_Proposal_Amount, #ODC_Amount, #Manager_Name, #Admin, #Due_Date, #Start_Date, #End_Date,
#Proposal_Number, #Contract_Type)
SET #NewId = SCOPE_IDENTITY()
END
RETURN #NewId
END
GO
I know it's something small I missed. But, my OUTCOME is that when you run the procedure, it inserts the values in the correct columns, and the primary key is auto updated without having to stick your own value into the statement. My execution of the statement would be as follows
EXEC Promotional.Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd','2020/08/30','2020/08/30','2020/08/30','fd','fd';
And I get this error:
Msg 201, Level 16, State 4, Procedure Promotional.Proposals_Create, Line 0 [Batch Start Line 0]
Procedure or function 'Proposals_Create' expects parameter '#NewId', which was not supplied.
I shouldn't have to provide that parameter because it should auto update with my PK which is Proposal_Uid. Or do I have to make my Proposal_Uid the value returned from ScopeIdentity?
#NewID should not be a parameter of the procedure since it is an IDENTITY column.
You can get the stored procedure to return the generated id by providing an output variable to store its content. This behaviour is also documented here.
declare #test int;
EXEC Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd',
'2020/08/30','2020/08/30','2020/08/30','fd','fd', #test OUTPUT;
select #test as 'new_identity';
set #test = null; -- because of the IF statement in your procedure...
EXEC Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd',
'2020/08/30','2020/08/30','2020/08/30','fd','fd', #test OUTPUT;
select #test as 'new_identity';
The selects return 1 and 2 respectively.
Fiddle (Remark: schema name removed in code above and in fiddle).

Write a trigger to update the columnB in TableB when the ColumnA in TableA are updated based on the common column in both the tables

CREATE TABLE [dbo].[USERS]
(
[USER_NAME] [nvarchar](64) NOT NULL,
[EMAIL_ADDRESS] [nvarchar](256) NULL,
[REGISTERED_DATE] [datetime] NOT NULL,
[FULL_NAME] [nvarchar](256) NOT NULL,
[MANAGER] [nvarchar](64) NULL,
[DEPARTMENT] [nvarchar](256) NULL,
[TITLE] [nvarchar](64) NULL,
PRIMARY KEY CLUSTERED ([USER_NAME] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
This is my table and I want the trigger to fire when the manager column is updated and the same values of the manage have to update on the another table based on the USER_NAME column.
i tried the the below trigger but it is not working.
Create TRIGGER [dbo].[UpdateManager]
ON [dbo].[USERS]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare #USER_NAME as nvarchar
declare #MANAGER as nvarchar
if(update(MANAGER))
begin
select #USER_NAME = USER_NAME from deleted
select #manager = Manager from deleted
update [dbo].[USERS_TEST] set MANAGER=#MANAGER where USER_NAME= #USER_NAME
end
END
You have two MAJOR issues in your trigger:
As mentioned in a comment, deleted can have multiple rows and you don't take that into account.
nvarchar has no length; the default in this case is a length of 1.
I suspect that the query you want is:
update ut
set MANAGER = d.MANAGER
from [dbo].[USERS_TEST] ut join
deleted d
on ut.USER_NAME = d.USER_NAME ;

Bypass duplicate record when one table data is inserted from another in SQL Server

I am trying to insert data from one database table to another database table. This work is performed very well but need bypass that duplicate data cannot be inserted. Here is my query below. How can I check duplicate record?
;WITH ABC AS (
SELECT
5 AS DeviceID
, nUserID AS CardNo
, CONVERT(DATE, dbo.fn_ConvertToDateTime(nDateTime)) AS InOutDate
, CONVERT(VARCHAR(8) ,CONVERT(TIME,dbo.fn_ConvertToDateTime(nDateTime))) AS InOutTime
FROM [BioStar].[dbo].[TB_EVENT_LOG]
)
SELECT * INTO #tempAtten FROM ABC
INSERT [HR].[dbo].[HR_DeviceInOut](DeviceID, CardNo, InOutDate, InOutTime, ShiftprofileID, ExecutedBy)
SELECT DeviceID, CardNo, InOutDate, InOutTime, NULL, NULL
FROM #tempAtten
WHERE #tempAtten.InOutDate = CONVERT(DATE, GETDATE()) AND #tempAtten.CardNo <> 0
DROP TABLE #tempAtten
--HR_DeviceInOut
CREATE TABLE [dbo].[HR_DeviceInOut](
[id] [bigint] IDENTITY(100000000000001,1) NOT NULL,
[DeviceID] [nvarchar](20) NULL,
[CardNo] [nvarchar](20) NOT NULL,
[InOutDate] [date] NOT NULL,
[InOutTime] [nvarchar](10) NOT NULL,
[ShiftprofileID] [tinyint] NULL,
[ExecutedBy] [int] NULL,
CONSTRAINT [PK_HR_AttenHistory] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Function
ALTER FUNCTION [dbo].[fn_ConvertToDateTime] (#Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
DECLARE #LocalTimeOffset BIGINT
,#AdjustedLocalDatetime BIGINT;
SET #LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET #AdjustedLocalDatetime = #Datetime - #LocalTimeOffset
RETURN (SELECT DATEADD(second,#AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;
Assuming I'm understanding correctly, here's one option using not exists:
INSERT [HR].[dbo].[HR_DeviceInOut] (DeviceID, CardNo, InOutDate,
InOutTime, ShiftprofileID, ExecutedBy)
SELECT DeviceID, CardNo, InOutDate, InOutTime, NULL, NULL
FROM #tempAtten t
WHERE t.InOutDate = CONVERT(DATE, GETDATE()) AND
t.CardNo <> 0 AND
NOT EXISTS (
SELECT 1
FROM [HR].[dbo].[HR_DeviceInOut] d
WHERE t.DeviceID = d.DeviceId AND
t.CardNo = d.CardNo AND
t.InOutDate = d.InOutDate AND
t.InOutTime = d.InOutTime
)
Consider adding a unique_index to the those fields that cannot be duplicated.
Which column set make record unique as i see some column are hard coded
ie 5 AS DeviceID ...
Create unique key for rest of the column in temp table and destinationtabel.to avoid duplicate .

use sql stored procedure to insert data which is returned from a query stored in a table

sql server 2005
I have a stored procedure which I used to insert data into a table. Some of the data will need to come from the results of executing a query that is stored in a separate table.
The main problem that I keep hitting is not being able to properly execute the returned query. I have tried creating several functions over the past couple of days based on other posts that I have read, but I keep hitting sql errors with exec, execute, sp_executesql, etc.
I am going to paste several scripts that you can use to replicate my environment. I am hoping that someone can please provide an actual code sample which will execute the returned query for use within the stored proc insert function.
Thank you!!!
CREATE TABLE [dbo].[CLIENT](
[cli_id] [int] IDENTITY(1,1) NOT NULL,
[cli_first_name] [varchar](100) NULL,
CONSTRAINT [PK__CLIENT__07F6335A] PRIMARY KEY CLUSTERED
(
[cli_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT INTO CLIENT (cli_first_name, cli_last_name) values ('tom', 'smith');
go
CREATE TABLE [dbo].[ASSESSMENT_DATALABEL_LIST](
[adl_ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[BoundName] [nvarchar](50) NOT NULL,
[Query] [ntext] NOT NULL,
[KeyFieldName] [nvarchar](50) NOT NULL,
[Status] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_ASSESSMENT_DATALABEL_LIST] PRIMARY KEY CLUSTERED
(
[adl_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT INTO ASSESSMENT_DATALABEL_LIST (Name, BoundName, Query, KeyFieldName, Status)
values ('Name, First', 'cli_first_name', 'select IsNull(cli_first_name,'''') as cli_first_name FROM CLIENT WHERE cli_id = #KeyFieldValue', 'cli_ID', 'Active')
go
INSERT INTO ASSESSMENT_DATALABEL_LIST (Name, BoundName, Query, KeyFieldName, Status)
values ('Name, Last', 'cli_last_name', 'select IsNull(cli_last_name,'''') as cli_last_name FROM CLIENT WHERE cli_id = #KeyFieldValue', 'cli_ID', 'Active')
go
CREATE TABLE [dbo].[Item_Source]
(
[Item_ID] [int] IDENTITY(1,1) NOT NULL,
[ItemType] [nvarchar](50) NOT NULL,
[ItemCaption] [nvarchar] (50) NULL,
[adl_ID] [int] NOT NULL
)
go
INSERT INTO Item_Source
(ItemType, ItemCaption, adl_ID) values
('DATALABEL', 'First Name',1)
go
INSERT INTO Item_Source
(ItemType, ItemCaption, adl_ID) values
('DATALABEL', 'Last Name',2)
go
CREATE TABLE [dbo].[Item_Destination]
(
[ItemType] [nvarchar](50) NOT NULL,
[ItemCaption] [nvarchar] (50) NULL,
[ItemValue] [nvarchar](50) NULL
)
go
CREATE PROCEDURE [dbo].[spInsertStuff]
#cli_id int
AS
INSERT INTO Item_Destination
(ItemType, ItemCaption, ItemValue)
SELECT
ItemType, ItemCaption, [[[ VALUE OF EXECUTED QUERY FROM ADL TABLE --- dbo.FunctionToGetResultsOfStoredQuery(Item_Source.adl_id, #cli_id) ]]]
FROM Item_Source WHERE Item_Source.Item_ID IN (1,2)
-- this insert will insert both Item_Source rows into Item_Dest with one call. The first row should have an ItemValue of Tom, the second row should have an ItemValue of Smith
GO
You may check this fiddle
The code of the Stored Procedure is:
CREATE PROCEDURE [dbo].[spInsertStuff]
#cli_id int
AS
DECLARE #SQL AS VARCHAR(MAX)
DECLARE #ADL_ID AS INT
DECLARE MyCURSOR
CURSOR FOR
SELECT QUERY, ADL_ID FROM ASSESSMENT_DATALABEL_LIST
OPEN MyCURSOR
FETCH NEXT FROM MyCURSOR INTO #SQL, #ADL_ID
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = REPLACE(#SQL,'#KeyFieldValue',#cli_id)
DECLARE #Temp AS TABLE ([Value] [nvarchar](50))
INSERT INTO #Temp
EXEC (#SQL)
INSERT INTO Item_Destination
(ItemType, ItemCaption, ItemValue)
SELECT
ItemType, ItemCaption, (SELECT [Value] FROM #Temp)
FROM Item_Source
WHERE Item_Source.adl_ID = #ADL_ID
DELETE FROM #Temp
FETCH NEXT FROM MyCURSOR INTO #SQL, #ADL_ID
END
CLOSE MyCURSOR
DEALLOCATE MyCURSOR
GO

SQL Lookup List

I have been asked to create a table in SQL and am not sure about one of the table fields.
I have been asked to create a table with the following information:
First Name
Last Name
Three Address Lines
Mobile Phone
Home Phone
Date Modified
Person Category
Comment
This is the description for the Person Category:
Person Category:
Simple Lookup List contained in the database, (ID and Description), can pre-populate this data from the script, no need to edit and update from the VB application. Category descriptions are: Client, Worker, Assessor, and Unknown.
Can someone please explain to me what is needed here?
UPDATE
Here is my current script for the Person table:
CREATE TABLE db_person.Person
(
PersonID NUMBER NOT NULL,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
AddressLine1 varchar(50),
AddressLine2 varchar(50),
AddressLine3 varchar(50),
MobilePhone varchar(20),
HomePhone varchar(20),
DateModified DATE,
PersonCategory varchar(50),
Comment varchar(8000),
PRIMARY KEY (PersonID)
)
Can I have some help to create the Lookup List for the PersonCategory and to link it into the Person Table?
It means that you need to create another table for the Person Category. Thus a one-to-many relationship between the 2 tables.
Moreover because the description of a person is limited to either Client, Worker, Assessor or Unknown, you should be handle this in your script creation by using the keyword "CHECK".
i.e.
CHECK (Description in ("Client", "Worker", "Assessor", "Unknown"))
First of all you must create the Categories lookup table. You could create it with a script like this:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Categories](
[Id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[Description] [varchar](50) NOT NULL,
CONSTRAINT [PK_Categories] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
ALTER TABLE [Categories] ADD CONSTRAINT [DF_Categories_Id] DEFAULT (newid()) FOR [Id]
GO
and populate it with the 4 descriptions:
INSERT INTO Categories ([Description])
VALUES ('Client')
INSERT INTO Categories ([Description])
VALUES ('Worker')
INSERT INTO Categories ([Description])
VALUES ('Assessor')
INSERT INTO Categories ([Description])
VALUES ('Unknown')
After that, you must create the Persons table, with the constraint with the Categories table:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [Persons](
[Id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[IdCategory] [uniqueidentifier] NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[FirstAddress] [varchar](250) NULL,
[SecondAddress] [varchar](250) NULL,
[ThirdAddress] [varchar](250) NULL,
[HomePhone] [varchar](50) NULL,
[MobilePhone] [varchar](50) NULL,
[Modified] [datetime] NOT NULL,
[Comment] [varchar](500) NULL,
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
ALTER TABLE [Persons] ADD CONSTRAINT [DF_Persons_Id] DEFAULT (newid()) FOR [Id]
GO
ALTER TABLE [Persons] WITH CHECK ADD CONSTRAINT [FK_Persons_Categories] FOREIGN KEY([IdCategory])
REFERENCES [Categories] ([Id])
GO
ALTER TABLE [Persons] CHECK CONSTRAINT [FK_Persons_Categories]
GO
Now you have the two tables :)
These scripts run on Microsoft SQL Server.
PS: Best practice is to do another table for multiple addresses and multiple phones ;)
To retrieve data with the SELECT, you could do:
SELECT FirstName, LastName, Description AS Category
FROM Persons INNER JOIN
Categories ON Categories.Id = Persons.IdCategory
If you're using NUMBER for the IDs, change the IdCategory datatype in NUMBER. After that, the storedprocedure could be like:
CREATE PROCEDURE [AddPerson]
(
#Category varchar(50),
#FirstName varchar(50),
#LastName varchar(50),
#FirstAddress varchar(250) = NULL,
#SecondAddress varchar(250) = NULL,
#ThirdAddress varchar(250) = NULL,
#HomePhone varchar(50) = NULL,
#MobilePhone varchar(50) = NULL,
#Comment varchar(500) = NULL
)
AS BEGIN
Declare #idCategory NUMBER
Set #idCategory = SELECT Id FROM Categories WHERE Description = Category
INSERT INTO Persons ([IdCategory], [FirstName], [LastName],
[FirstAddress],
[SecondAddress],
[ThirdAddress],
[HomePhone],
[MobilePhone],
[Modified],
[Comment])
VALUES (#idCategory,
#FirstName,
#LastName,
#FirstAddress,
#SecondAddress,
#ThirdAddress,
#HomePhone,
GETDATE(),
#MobilePhone,
#Comment)
END
GO
I'm sorry if this codes contains some errors but I wrote it with notepad :)