So I am making a very simple update procedure, like I have done before, but when I run the execution through it, it does not update. I have looked this over several times and do not see any error in why it wouldn't cause the update to pass through it. My manual updates are working fine, so I am thinking I am either missing something super-obvious or this is something going on with the coalesce function. Any help would be great. The more eyes the merrier.
USE AdventureWorks2012
GO
CREATE PROCEDURE UpdateCreditCard
#CreditCardID INT,
#CardType nvarchar(50) = NULL,
#CardNumber nvarchar(25) = NULL,
#ExpMonth tinyint = NULL,
#ExpYear smallint = NULL
AS
BEGIN
UPDATE [Sales].[CreditCard]
SET
#CardType = COALESCE(#CardType,CardType),
#CardNumber = COALESCE(#CardNumber,CardNumber),
#ExpMonth = COALESCE(#ExpMonth,ExpMonth),
#ExpYear = COALESCE(#ExpYear,ExpYear)
FROM Sales.CreditCard
WHERE #CreditCardID = CreditCardID
END
EXECUTE UpdateCreditCard
#CreditCardID = 19267,
#CardType = 'MasterCard',
#CardNumber = '99999999',
#ExpMonth = 4,
#ExpYear = 2025
You are updating the variables not the columns in CreditCard table.
.....
SET
#CardType = COALESCE(#CardType,CardType), -- here you are updating the #CardType variable
.....
Try this.
CREATE PROCEDURE UpdateCreditCard
#CreditCardID INT,
#CardType nvarchar(50) = NULL,
#CardNumber nvarchar(25) = NULL,
#ExpMonth tinyint = NULL,
#ExpYear smallint = NULL
AS
BEGIN
UPDATE [Sales].[CreditCard]
SET
CardType = COALESCE(#CardType,CardType),
CardNumber = COALESCE(#CardNumber,CardNumber),
ExpMonth = COALESCE(#ExpMonth,ExpMonth),
ExpYear = COALESCE(#ExpYear,ExpYear)
FROM Sales.CreditCard
WHERE CreditCardID=#CreditCardID
END
Related
I have the following code when inputting parameters for a SP:
USE [MDAmanager]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[spCougarExport]
#PropertyCodeString = NULL,
#Date = NULL,
#InferDate = NULL,
#TransactionCodeString = NULL
SELECT 'Return Value' = #return_value
GO
For the #PropertyCodeString I would like to pass the values from a seperate table with all the property codes.
Below is an example of the property codes
What I'm trying to achieve is have the SP always return all properties and not require updating the property codes when a new property is added.
Any assistance or direction would be greatly appreciated.
Assuming you are able to amend your SP then you can utilise a user defined table type e.g.
CREATE TYPE [dbo].[PropertyCode_UDT] AS TABLE
( [PropertyCode] [bigint] NOT NULL
)
GO
DECLARE #PCTab [dbo].[PropertyCode_UDT]
;
INSERT INTO #PCTab
( [PropertyCode]
)
SELECT PC.[PropertyCode]
FROM [dbo].[PropertyCode] PC
;
DECLARE #return_value int
EXEC #return_value = [dbo].[spCougarExport]
#PropertyCode = #PCTab,
#Date = NULL,
#InferDate = NULL,
#TransactionCodeString = NULL
;
Your Sp will need to be amended to accept the correct type for #PropertyCode and you can just join your query within the SP on this table to get all the Property Codes
Eg
CREATE PROCEDURE [dbo].[spCougarExport]
#Date [date]
, #InferDate [date]
, #TransactionCodeString [nvarchar] (MAX)
, #PropertyCode PropertyCode_UDT READONLY
AS BEGIN;
.......
SELECT ...
FROM #PropertyCode atPC
I am new to SQL Server and T-SQL, but I do have some experience building applications in MS Access.
This stored procedure runs fine when I execute it from the application, however when I am debugging it in SSMS, I get an error
Unable to Step. Invalid Operation.
but it will allow me to step through. Based on my research, it seems like I am creating a race condition but I have not been able to correctly fix the issue. I would also appreciate any advice to optimize this or fix any issues that are apparent.
What the code does:
This code is to enter a new customer into the database. The first select statement looks for an existing ID. If the ID is null, it will add a new customer. If the ID is not null, it will not add the customer. The same goes for the second IF statement to check if #pName2 and #pName3 are null before inserting these values.
Here is my code:
#pUID nvarchar(16) = null,
#pName1 nvarchar(50) = null,
#pName2 nvarchar(50) = null,
#pName3 nvarchar(50) = null,
#pAddress1 nvarchar(30) = null,
#pAddress2 nvarchar(30) = null,
#pAddress3 nvarchar(30) = null,
#pZipCode nvarchar(30) = null
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ID INT
SELECT #ID = ID FROM tblCustomer WHERE strUID = #pUID
IF #ID IS NULL
BEGIN
DECLARE #Customer_ID INT
INSERT INTO tblCustomer(strUID, strName)
VALUES(#pUID, #pName1)
SET #Customer_ID = ##IDENTITY
IF (#pName2 <> '') OR (#pName3 <> '')
BEGIN
INSERT INTO tblSecondaryCustomer(CustomerID, strName2, strName3)
VALUES(#Customer_ID, #pName2, #pName3)
END
INSERT INTO tblAddress(CustomerID, strAddress1, strAddress2, strAddress3, strZipCode)
VALUES(#Customer_ID, #pAddress1, #pAddress2, #pAddress3, #pZipCode)
END
END
Try replacing your IF statement with the following:
IF NOT EXISTS(SELECT ID FROM tblCustomer WHERE strUID = #pUID)
It doesn't seem your using #ID other than a check for existence...and you can use the ISNULL function to make sure you cover NULL cases...
IF (ISNULL(#pName2,'') <> '') OR (ISNULL(#pName3,'') <> '')
HTH
Dave
My insert procedure is working fine the way i want. But update is not working with scope identity.
SET ANSI_NULLS ON
ALTER PROCEDURE [dbo].[spr_unitCreation]
(
#Unit_Name VARCHAR(50) = NULL,
#Unit_Abbreviation VARCHAR(50) = NULL,
#Unit_type VARCHAR(50) = NULL,
#Decimal_Places VARCHAR(50) = NULL,
#Description VARCHAR(50) = NULL,
#Super_Unit VARCHAR(50) = NULL,
#Per_Unit VARCHAR(50) = NULL,
#unit_Id INT OUTPUT,
#abc VARCHAR(50) = NULL
)
AS
BEGIN
IF #abc = 'update' BEGIN
SET NOCOUNT ON;
SELECT #unit_Id AS SCOPE_IDENTITY
UPDATE tbl_UnitCreation
SET Unit_Name = #Unit_Name,
Unit_Abbreviation = #Unit_Abbreviation,
Unit_type = #Unit_type,
Decimal_Places = #Decimal_Places,
Description = #Description,
Super_Unit = #Super_Unit,
Per_Unit = #Per_Unit
WHERE unit_Id = #unit_Id
END
END
SELECT * FROM tbl_UnitCreation
SCOPE_IDENTITY returns the last identity value inserted into an identity column. You are not inserting a row.
To update a row all you need is to pass a value to #unit_Id when executing [spr_unitCreation]. Also remove the line "SELECT #unit_Id AS SCOPE_IDENTITY" from your code.
Based on the comments, you need to find the correct id by searching on relevant details. So you can get the id like this:
SELECT #unit_Id = unit_Id
FROM tbl_UnitCreation
WHERE Unit_Name=#Unit_Name -- NB: Ensure this column contains your relevant details
Another commonly used option is to use the OUTPUT clause of the UPDATE statement, inserting all the updated/"inserted" primary keys and Unit_name into a tablevariable.
https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017
I wrote a stored procedure that filters my table. It is working fine, and selects the correct records, but in the result for example if query have to return one record.
Instead of one record return too many record is it possible my stored procedure executes several times?
I use this code:
ALTER PROCEDURE [dbo].[propertyFilterByCity]
#city NVARCHAR(150) = NULL,
#DefaultPageIndex smallint = NULL,
#DefaultPageSize smallint = NULL,
#RecordCount bit = NULL,
#MinPrice decimal(18, 0) = NULL,
#MaxPrice decimal(18, 0) = NULL,
#bedRoom smallint = NULL,
#PropertyType NVARCHAR(20) = NULL,
#requestType NVARCHAR(20) = NULL,
#Parking bit = NULL,
#RemoteParking bit = NULL,
#Lobby bit = NULL,
#AssemblyHall bit = NULL,
#Gym bit = NULL,
#Surveillance bit = NULL,
#FireAlarm bit = NULL,
#FireFighting bit = NULL,
#Pool bit = NULL,
#Sauna bit = NULL,
#Jacuzzi bit = NULL,
#Carwash bit = NULL,
#Laundry bit = NULL,
#Custodian bit = NULL,
#Shooting bit = NULL,
#TheftAlarm bit = NULL,
#PanelFit bit = NULL,
#Sentry bit = NULL,
#CentralSatellite bit = NULL,
#CentralAntenna bit = NULL,
#Fireplaces bit = NULL,
#MasterRoom bit = NULL,
#Patio bit = NULL,
#Barbecue bit = NULL,
#UPS bit = NULL,
#RoofGarden bit = NULL
AS
BEGIN
BEGIN TRY
SET NOCOUNT ON ;
BEGIN TRANSACTION;
DECLARE #CityId int;
IF EXISTS(SELECT Estate_CityId FROM [^Estate_City] WHERE Estate_CityName = #city)
BEGIN
SET #CityId= (SELECT Estate_CityId FROM [^Estate_City] WHERE Estate_CityName = #city);
END
IF(#MinPrice IS NOT NULL AND #MaxPrice IS NOT NULL)
BEGIN
IF (#MaxPrice>0 AND #MaxPrice>#MinPrice)
BEGIN
DECLARE #results TABLE (RowNum INT,Estate_Code BIGINT,Estate_propertyType NVARCHAR(50),Estate_buildingArea NVARCHAR(20),Estate_floor NVARCHAR(10),Estate_neighborhoodProperty NVARCHAR(100),Estate_street1 NVARCHAR(100),
Estate_street2 NVARCHAR(100),Estate_visits BIGINT,houseImage NVARCHAR(MAX),houseImage1 NVARCHAR(MAX),houseImage2 NVARCHAR(MAX),houseImage3 NVARCHAR(MAX),houseImage4 NVARCHAR(MAX),Owner_requestType NVARCHAR(MAX),
Facility_Description NVARCHAR(MAX),Estate_BedRoomCount NVARCHAR(2))
INSERT INTO #results(RowNum,Estate_Code,Estate_propertyType,Estate_buildingArea,Estate_floor,Estate_neighborhoodProperty,Estate_street1,Estate_street2,Estate_visits,houseImage,houseImage1,
houseImage2,houseImage3,houseImage4,Owner_requestType,Facility_Description,Estate_BedRoomCount)
SELECT ROW_NUMBER() OVER(ORDER BY [^Estate].Estate_Code) AS [Row],[^Estate].Estate_Code,[^Estate].Estate_propertyType, [^Estate].Estate_buildingArea,[^Estate].Estate_floor,[^Estate].Estate_neighborhoodProperty,[^Estate].Estate_street1,[^Estate].Estate_street2,[^Estate].Estate_visits,[^Estate_Images].houseImage,[^Estate_Images].houseImage1,[^Estate_Images].houseImage2,[^Estate_Images].houseImage3,[^Estate_Images].houseImage4,[^Estate_OwnerInfo].RequestType_Type,[^Estate_Facility].Facility_descText,[^Estate].Estate_bedRoomCount
FROM [^Estate]
INNER JOIN [^Estate_Images] ON [^Estate].Estate_Code=[^Estate_Images].Estate_Code
INNER JOIN [^Estate_OwnerInfo] ON [^Estate].Owner_code=[^Estate_OwnerInfo].Owner_code
INNER JOIN [^Estate_Facility] ON [^Estate].Estate_Code=[^Estate_Facility].Estate_Code
INNER JOIN [^Estate_City] ON [^Estate].Estate_CityId =[^Estate].Estate_CityId
WHERE
(#CityId IS NULL OR [^Estate].Estate_CityId =#CityId ) AND
(#requestType IS NULL OR [^Estate_OwnerInfo].RequestType_Type = #requestType) AND
([^Estate].Estate_totalPrice BETWEEN #MinPrice AND #MaxPrice) AND
(#bedRoom IS NULL OR [^Estate].Estate_bedRoomCount>#bedRoom) AND
(#PropertyType IS NULL OR [^Estate].Estate_propertyType = #PropertyType) AND
(#requestType IS NULL OR [^Estate_OwnerInfo].RequestType_Type = #requestType) AND
(#bedRoom IS NULL OR [^Estate].Estate_bedRoomCount = #bedRoom) AND
(#Parking IS NULL OR [^Estate_Facility].Facility_Parking = #Parking) AND
(#RemoteParking IS NULL OR [^Estate_Facility].Facility_RemoteParking = #RemoteParking) AND
(#Lobby IS NULL OR [^Estate_Facility].Facility_Lobby = #Lobby)AND
(#Gym IS NULL OR [^Estate_Facility].Facility_Gym = #Gym) AND
(#Surveillance IS NULL OR [^Estate_Facility].Facility_Surveillance = #Surveillance) AND
(#FireAlarm IS NULL OR [^Estate_Facility].Facility_FireAlarm = #FireAlarm) AND
(#FireFighting IS NULL OR [^Estate_Facility].Facility_FireFighting = #FireFighting) AND
(#Pool IS NULL OR [^Estate_Facility].Facility_Pool = #Pool) AND
(#Sauna IS NULL OR [^Estate_Facility].Facility_Sauna = #Sauna) AND
(#Jacuzzi IS NULL OR [^Estate_Facility].Facility_Jacuzzi = #Jacuzzi) AND
(#Carwash IS NULL OR [^Estate_Facility].Facility_Carwash = #Carwash) AND
(#Laundry IS NULL OR [^Estate_Facility].Facility_Laundry = #Laundry) AND
(#Custodian IS NULL OR [^Estate_Facility].Facility_Custodian = #Custodian) AND
(#Shooting IS NULL OR [^Estate_Facility].Facility_Shooting = #Shooting) AND
(#TheftAlarm IS NULL OR [^Estate_Facility].Facility_TheftAlarm = #TheftAlarm) AND
(#PanelFit IS NULL OR [^Estate_Facility].Facility_PanelFit = #PanelFit) AND
(#Sentry IS NULL OR [^Estate_Facility].Facility_Sentry = #Sentry) AND
(#CentralSatellite IS NULL OR [^Estate_Facility].Facility_CentralSatellite = #CentralSatellite) AND
(#CentralAntenna IS NULL OR [^Estate_Facility].Facility_CentralAntenna = #CentralAntenna) AND
(#Fireplaces IS NULL OR [^Estate_Facility].Facility_Fireplaces = #Fireplaces) AND
(#MasterRoom IS NULL OR [^Estate_Facility].Facility_MasterRoom = #MasterRoom) AND
(#Patio IS NULL OR [^Estate_Facility].Facility_Patio = #Patio) AND
(#Barbecue IS NULL OR [^Estate_Facility].Facility_Barbecue = #Barbecue) AND
(#UPS IS NULL OR [^Estate_Facility].Facility_UPS= #UPS) AND
(#RoofGarden IS NULL OR [^Estate_Facility].Facility_RoofGarden = #RoofGarden)
END
END
select * from #results order by Estate_Code;
DECLARE #ErrorCode INT;
DECLARE #Result INT;
SET #ErrorCode = ##ERROR;
IF (#ErrorCode <> 0)
BEGIN
ROLLBACK TRANSACTION;
SET #Result=0;
EXEC Debug_InsertSQLErrorDetails
END
ELSE
BEGIN
COMMIT TRANSACTION;
SET #Result=SCOPE_IDENTITY();
END
END TRY
BEGIN CATCH
SET NOCOUNT OFF
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END
EXEC Debug_InsertSQLErrorDetails
SET #Result=0;
END CATCH
END
Please help me to solve this problem thanks!
First of all, a stored procedure will not run multiple times.
The reason could be thatfrom the Estate table you join multiple tables. If these joins are not 1 to 1, but 1 to n, you'll get a result row for each possible join.
Eg, if an Estate has multiple images, you'll get a row for each estate image in your result.
Ok, I created a Stored Procedure that, among other things, is searching 5 columns for a particular keyword. To accomplish this, I have the keywords parameter being split out by a function and returned as a table. Then I do a Left Join on that table, using a LIKE constraint.
So, I had this working beautifully, and then all of the sudden it stops working. Now it is returning every row, instead of just the rows it needs.
The other caveat, is that if the keyword parameter is empty, it should ignore it.
Given what's below, is there A) a glaring mistake, or B) a more efficient way to approach this?
Here is what I have currently:
ALTER PROCEDURE [dbo].[usp_getOppsPaged]
#startRowIndex int,
#maximumRows int,
#city varchar(100) = NULL,
#state char(2) = NULL,
#zip varchar(10) = NULL,
#classification varchar(15) = NULL,
#startDateMin date = NULL,
#startDateMax date = NULL,
#endDateMin date = NULL,
#endDateMax date = NULL,
#keywords varchar(400) = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH Results_CTE AS
(
SELECT opportunities.*,
organizations.*,
departments.dept_name,
departments.dept_address,
departments.dept_building_name,
departments.dept_suite_num,
departments.dept_city,
departments.dept_state,
departments.dept_zip,
departments.dept_international_address,
departments.dept_phone,
departments.dept_website,
departments.dept_gen_list,
ROW_NUMBER() OVER (ORDER BY opp_id) AS RowNum
FROM opportunities
JOIN departments ON opportunities.dept_id = departments.dept_id
JOIN organizations ON departments.org_id=organizations.org_id
LEFT JOIN Split(',',#keywords) AS kw ON
(title LIKE '%'+kw.s+'%' OR
[description] LIKE '%'+kw.s+'%' OR
tasks LIKE '%'+kw.s+'%' OR
requirements LIKE '%'+kw.s+'%' OR
comments LIKE '%'+kw.s+'%')
WHERE
(
(#city IS NOT NULL AND (city LIKE '%'+#city+'%' OR dept_city LIKE '%'+#city+'%' OR org_city LIKE '%'+#city+'%'))
OR
(#state IS NOT NULL AND ([state] = #state OR dept_state = #state OR org_state = #state))
OR
(#zip IS NOT NULL AND (zip = #zip OR dept_zip = #zip OR org_zip = #zip))
OR
(#classification IS NOT NULL AND (classification LIKE '%'+#classification+'%'))
OR
((#startDateMin IS NOT NULL AND #startDateMax IS NOT NULL) AND ([start_date] BETWEEN #startDateMin AND #startDateMax))
OR
((#endDateMin IS NOT NULL AND #endDateMax IS NOT NULL) AND ([end_date] BETWEEN #endDateMin AND #endDateMax))
OR
(
(#city IS NULL AND
#state IS NULL AND
#zip IS NULL AND
#classification IS NULL AND
#startDateMin IS NULL AND
#startDateMax IS NULL AND
#endDateMin IS NULL AND
#endDateMin IS NULL)
)
)
)
SELECT *
FROM Results_CTE
WHERE RowNum >= #startRowIndex
AND RowNum < #startRowIndex + #maximumRows;
END
Query -
Can you show us the Previous version that was working?
Are you using any source control to keep track of the changes made?
My Suggestions
Like Predicate with %% seems very expensive and slow process. Is it possible for you to user Full Text Index ?
Declare local variable for each Input Parameter. Assign the corresponding column name to this variable. In case of City, as three columns are being used, so declare three variables for City and assign the corresponding column names, Like below...
Set #Local_city = 'city'
Set #Local_dept_city = 'dept_city'
finally you can use it in the Where clause. Doing this will exclude the below lines of code.
OR
(
(#city IS NULL AND
#state IS NULL AND
#zip IS NULL AND
#classification IS NULL AND
#startDateMin IS NULL AND
#startDateMax IS NULL AND
#endDateMin IS NULL AND
#endDateMin IS NULL)
So, I had this working beautifully, and then all of the sudden it
stops working. Now it is returning every row, instead of just the rows
it needs.
Are you sure about the operators being used in the query? I mean everywhere you have OR operator.
The other caveat, is that if the keyword parameter is empty, it should
ignore it.
Please check my above suggestion.
Final Query
ALTER PROCEDURE [dbo].[usp_getOppsPaged]
#startRowIndex int,
#maximumRows int,
#city varchar(100) = NULL,
#state char(2) = NULL,
#zip varchar(10) = NULL,
#classification varchar(15) = NULL,
#startDateMin date = NULL,
#startDateMax date = NULL,
#endDateMin date = NULL,
#endDateMax date = NULL,
#keywords varchar(400) = NULL
AS
BEGIN
SET NOCOUNT ON;
Declare #Local_city varchar(100)
declare #Local_dept_city varchar(100)
declare #Local_org_city varchar(100)
Declare #Local_state char(2)
Declare #Local_dept_state char(2)
Declare #Local_org_state char(2)
Declare #Local_zip varchar(10)
Declare #Local_dept_zip varchar(10)
Declare #Local_org_zip varchar(10)
Declare #Local_classification varchar(15)
Declare #Local_startDateMin date
Declare #Local_startDateMax date
Declare #Local_endDateMin date
Declare #Local_endDateMin date
Declare #Local_endDateMax date
Set #Local_city = 'city'
Set #Local_dept_city = 'dept_city'
Set #Local_org_city = 'org_city'
Set #Local_state = 'state'
Set #Local_dept_state = 'dept_state'
Set #Local_org_state = 'org_state'
Set #Local_zip = 'zip'
Set #Local_dept_zip = 'dept_zip'
Set #Local_org_zip = 'org_zip'
Set #Local_classification = 'classification'
Set #Local_startDateMax = 'startDateMax'
Set #Local_endDateMin = 'endDateMin'
Set #Local_endDateMin = 'endDateMin'
Set #Local_endDateMax = 'endDateMax'
;WITH Results_CTE AS
(
SELECT opportunities.*,
organizations.*,
departments.dept_name,
departments.dept_address,
departments.dept_building_name,
departments.dept_suite_num,
departments.dept_city,
departments.dept_state,
departments.dept_zip,
departments.dept_international_address,
departments.dept_phone,
departments.dept_website,
departments.dept_gen_list,
ROW_NUMBER() OVER (ORDER BY opp_id) AS RowNum
FROM opportunities
JOIN departments ON opportunities.dept_id = departments.dept_id
JOIN organizations ON departments.org_id=organizations.org_id
LEFT JOIN Split(',',#keywords) AS kw ON
(title LIKE '%'+kw.s+'%' OR
[description] LIKE '%'+kw.s+'%' OR
tasks LIKE '%'+kw.s+'%' OR
requirements LIKE '%'+kw.s+'%' OR
comments LIKE '%'+kw.s+'%')
WHERE
(
(#city IS NOT NULL AND (city LIKE '%'+#Local_city+'%' OR dept_city LIKE '%'+#Local_dept_city+'%' OR org_city LIKE '%'+#Local_org_city+'%'))
OR
(#state IS NOT NULL AND ([state] = #Local_state OR dept_state = #Local_dept_state OR org_state = #Local_org_state))
OR
(#zip IS NOT NULL AND (zip = #Local_zip OR dept_zip = #Local_dept_zip OR org_zip = #Local_org_zip))
OR
(#classification IS NOT NULL AND (classification LIKE '%'+#Local_classification+'%'))
OR
((#startDateMin IS NOT NULL AND #Local_startDateMax IS NOT NULL) AND ([start_date] BETWEEN #Local_startDateMax AND #Local_startDateMax))
OR
((#endDateMin IS NOT NULL AND #Local_endDateMax IS NOT NULL) AND ([end_date] BETWEEN #Local_endDateMin AND #Local_endDateMax))
)
)
SELECT *
FROM Results_CTE
WHERE RowNum >= #startRowIndex
AND RowNum < #startRowIndex + #maximumRows;
END