how use replace in exec statement in sql server 2008 - sql

I have a stored proc, say, "call_Me" with few parameters:
Declare #Greet varchar(100) = 'Hi ||User||'
Exec Call_Me 1,'something', #Greet --parameters: bit, string, string
during the call, I want to be able to replace the
||User||
bit with something else. normally, in a select statement, I would do this:
select 1, 'something', Replace(#Greet, '||User||', u.Username) from UserTable
which works fine, But today, for the first time, I am trying to use it in exec statement, the error says its expecting select, I tried adding select in every possible (and sensible) way but it just didnt seem to work out.
How can I use a replace during an execute statement call?
Many thanks in advance!

You'd need to format #Greet before passing it to the sproc:
Declare #Greet varchar(100) = 'Hi ||User||'
SELECT #Greet = Replace(#Greet, '||User||', u.Username)
FROM UserTable u
WHERE Id = 1
Exec Call_Me 1,'something', #Greet --parameters: bit, string, string

You can only use a literal or a variable reference in a procedure call:
[ { EXEC | EXECUTE } ]
{
[ #return_status= ]
{ module_name [ ;number ] | #module_name_var }
[ [ #parameter= ] { value
| #variable [ OUTPUT ]
| [ DEFAULT ]
}
]
[ ,...n ]
[ WITH RECOMPILE ]
}
[;]
Use this:
Declare #Greet varchar(100) = 'Hi ||User||'
Declare #param VARCHAR(100) = REPLACE(#Greet, '||User||', 'replacement')
Exec Call_Me 1,'something', #param

I am not sure if I understand correctly your problem, but maybe using cursor solves your problem:
DECLARE CURSOR users LOCAL FAST_FORWARD FOR
SELECT
username
FROM
usertable
OPEN
DECLARE #username NVARCHAR(50)
DECLARE #Greet VARCHAR(100) = 'Hi ||User||'
FETCH NEXT FROM users INTO #username
WHILE ##FETCH_STATUS = 0 BEGIN
EXEC Call_Me 1, 'something', REPLACE(#Greet, '||User||', #username)
FETCH NEXT FROM users INTO #username
END
CLOSE users
DEALLOCATE users
If you don't need to call it in loop you can try something like (this can be a new stored procedure):
DECLARE #username NVARCHAR(50)
DECLARE #Greet VARCHAR(100) = 'Hi ||User||'
SELECT
#username = username
FROM
usernames
WHERE
user_id = 1
IF ##ROWCOUNT = 1 BEGIN
EXEC Call_Me 1, 'something', REPLACE(#Greet, '||User||', #username)
END

Related

Json input of a stored Procedure

I have a Stored Procedure with a JSON in input ,Is it possible to use the JSON as input for a stored procedure? how could i do that ?
CREATE PROCEDURE [warm].[stored _table]
(
#Json NVARCHAR(MAX)
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN
WITH JsonToTable AS
(
SELECT * FROM OPENJSON (#Json) WITH (
[type] [nvarchar](100),
[source] [nvarchar](38),
[time] [nvarchar](28),
[ID] [varchar](50) '$.data.ID',
[RegionCode] [varchar](10)'$.data.RegionCode'
[DueDate] [datetime2](7)'$.data.DueDate',
[SchedulStartDate] [datetime2](7)'$.data.SchedulStartDate',
)
)
MERGE [warm].[table] AS TARGET
USING JsonToTable AS SOURCE
ON (TARGET.ID = SOURCE.ID)
WHEN MATCHED THEN
UPDATE SET
TARGET.[RegionCode] = (SOURCE.[RegionCode]
TARGET.[DueDate] = [dbo].[ufn_cast_string_to_date](SOURCE.[DueDate])
,TARGET.[SchedulStartDate] = [dbo].[ufn_cast_string_to_date](SOURCE.[SchedulStartDate])
WHEN NOT MATCHED THEN
INSERT
(
[SourceID]
,[ID]
,[RegionCode]
,[DueDate]
,[SchedulStartDate])
VALUES
(
1
,[ID]
,[RegionCode]
,[dbo].[ufn_cast_string_to_date](SOURCE.[DueDate])
,[dbo].[ufn_cast_string_to_date](SOURCE.[SchedulStartDate])
);
END
END TRY
END
I Want to execute it with the request below :
DECLARE #return_value int
EXEC #return_value = [warm].[usp_upsert_warm_table]
#Json = N'{
"type" : "table",
"source" : "informations",
"time" : "2018-04-05T17:31:00Z",
"id" : "A11-111-111",
"data" : {"
"ID":"123-56",
"RegionCode":"2",
"DueDate":"2020-13-14T10:54:00",
"SchedulStartDate":"2020-12-14T10:54:00"
}'}
I get this Message Error :
JSON text is not properly formatted. Unexpected character '.' is found at position 480.**
This is the Valid input :
DECLARE #return_value int
EXEC #return_value = [warm].[usp_upsert_warm_table]
#Json = N'
{
"type" : "table1",
"source" : "",
"id" : "A111-111-11",
"time" : "2020-12-14 10:54:00",
"data" :{
"ApplicationID":"INFORMATIONS",
"ID":"157faf1657c-100",
"RegionCode":"2",
"DueDate":"2020-12-14 10:54:00",
"SchedulStartDate":"2020-12-14 10:54:00"}'}
For my input date : 2020-12-14 10:54:00 i deleteed the T in the middle
for my S.P : I change the type of My variables from datetime To varchar :
CREATE PROCEDURE [warm].[usp_upsert_warm_table]
...
[ID] [varchar](50) '$.data.ID',
[RegionCode] [varchar](10)'$.data.RegionCode'
[DueDate] [varchar](40)'$.data.DueDate',
[SchedulStartDate] [varchar](10)'$.data.SchedulStartDate',
....

Replacing a string pattern - SQL Server

I have a VARCHAR Column called CompanyInformation that contains some Json data inside of it, here is a example of what is being stored inside of this column.
{
"tradeName": "example",
"corporateName": "example",
"phone": "example",
"nationalExpansions": [
{
"id": 0,
"nameFranchise": "example",
"phoneNumber": "example",
"mobileNumber": "example",
"email": "example#example.com.br"
},
{
"id": 0,
"nameFranchise": "example",
"phoneNumber": "example",
"mobileNumber": "example",
"email": "example"
},
What i have to do is replace all emails inside of this file to one specific email, i was trying to use the REPLACE function to do that, but i don`t know exactly how to do pattern matching in SQL.
UPDATE MyExampleTable SET CompanyInformation = REPLACE(CONVERT(VARCHAR(MAX), CompanyInformation), '"email": "%%"', '"email": "tests#gmail.com.br"')
But it doesn't work, the UPDATE gets executed, but he never replace the email information because he doesn't find any matching pattern.
After some research and thanks to the help of a teammate, we've managed to find a solution to this problem, so i will post here to help anyone with the same problem.
This is the script:
DECLARE #text VARCHAR(max)
DECLARE #start INT = 0
DECLARE #begin INT = 0
DECLARE #end INT = 0
DECLARE #Id INT
DECLARE curEmail CURSOR
FOR
SELECT Id, CompanyInformation
FROM MyExampleTable
--WHERE id = 1
OPEN curEmail
FETCH NEXT FROM curEmail INTO #Id, #text
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #start = CHARINDEX('"email":"', #text) + 9;
SET #begin = #start
WHILE 1 = 1
BEGIN
--print 'end='+cast(#end as varchar(4))
SELECT #start = CHARINDEX('"email":"', #text, #end) + 9;
IF #begin <= #start
SET #begin = #start
ELSE
BREAK
SELECT #end = CHARINDEX('"', #text, #start)
SET #text = STUFF(#text, #start, #end - #start, 'tests#gmail.com.br')
END
print #text
update MyExampleTable set CompanyInformation= #text where id =#id
FETCH NEXT FROM curEmail INTO #Id, #text
END
CLOSE curEmail
DEALLOCATE curEmail

SQL use return value of function as procedure parameter

Let's define:
create table cities
(
ID int identity,
name varchar(50) unique
)
create function getID (#name varchar(50)) returns int
begin
declare #id int
select #id=ID from cities where name=#name
return #id
end
create procedure addLine
#cityID int
as begin
...
end
Is it possible to execute a procedure with value returned by function, as follows?
exec addLine getID('Warsaw')
exec addLine dbo.getID('Warsaw')
exec addLine (select dbo.getID('Warsaw'))
I tried above and it did not help.
Microsoft says that this is not possible. You can not pass result of a function to procedure as a parameter:
[ { EXEC | EXECUTE } ]
{
...
[ [ #parameter = ] { value
| #variable [ OUTPUT ]
| [ DEFAULT ]
}
]
...
}
[;]
So, only constant values, variables and DEFAULT keyword are permitted.
2 possible ways of doing this are:
1: declare variable
declare #i int = dbo.getID('Warsaw')
exec addLine #i
2: use dynamic query
DECLARE #cmd NVARCHAR(MAX) = 'exec addLine ' + CAST(dbo.getID('Warsaw') AS NVARCHAR(MAX))
EXEC(#cmd)
This will "execute a procedure with value returned by function"
It just won't do it 'inline'
declare #id int
select #id = dbo.getID('Warsaw')
exec addLine #id

Comparing two nvarchar in a function

In a function I want to check whether passed value is equal to a predefined value (#ValX)
I have wrote following function:
ALTER Function IsNotInReview(#Val NVARCHAR(MAX))
RETURNS BIT
AS
BEGIN
DECLARE #ValX NVARCHAR(MAX)
SET #ValX = '
{
"httpCode" : 200,
"message" : "OK",
"result" : {
"items" : {
"items" : [ ]
}
}
}
'
IF LTRIM(RTRIM(#Val)) = LTRIM(RTRIM(#ValX))
BEGIN
RETURN 1
END
ELSE
BEGIN
RETURN 0
END
RETURN 0
END
When I test call the function, I am always getting false value
SELECT dbo.IsNotInReview('
{
"httpCode" : 200,
"message" : "OK",
"result" : {
"items" : {
"items" : [ ]
}
}
}
')--should return true
SELECT dbo.IsNotInReview('test')
UPDATE
I have updated my SP but still getting the same 'false' return value
ALTER Function IsNotInReview(#Val NVARCHAR(MAX))
RETURNS BIT
AS
BEGIN
DECLARE #ValX NVARCHAR(MAX)
SET #ValX = '
{
"httpCode" : 200,
"message" : "OK",
"result" : {
"items" : {
"items" : [ ]
}
}
}
'
DECLARE #ReturnVal BIT
IF LTRIM(RTRIM(#Val)) = LTRIM(RTRIM(#ValX))
BEGIN
SET #ReturnVal = 1
END
ELSE
BEGIN
SET #ReturnVal = 0
END
RETURN #ReturnVal
END
SELECT dbo.IsNotInReview('{
"httpCode" : 200,
"message" : "OK",
"result" : {
"items" : {
"items" : [ ]
}
}
}') --Return false which is unexpected
You are not comparing identical strings. Look at the indentation. I cannot imagine that this is what your intention is, i.e. comparing not only relevant content but also indentation.
A possible solution is to remove all white spaces, line breaks etc. in the string, while skipping over sections enclosed in double quotes.
Edit: Here is a little function which might be useful for you. It removes white spaces from your string while skipping quoted regions. Please test thoroughly, I only wrote it and testet it a bit (I have to go to work now)
create function RemoveWhiteSpaces (#String nvarchar(max))
returns nvarchar(max)
as
begin
declare #result nvarchar(max), #i int, #n int, #inQuotes bit,
declar #c0 nchar(1), #c nchar(1)
set #i=1
set #n=len(#string)
set #result=''
set #inQuotes=0
set #c='x'
while #i <= #n begin
set #c0=#c
set #c=substring(#string,#i,1)
if #c='"' and #c0 != '\'
set #inQuotes= 1 - #inQuotes
if #inQuotes = 1 or
(#inQuotes = 0 and #c not in (' ',char(13), char(10),char(8)))
set #result = #result + #c
set #i=#i+1
end
return #result
end

How to store the result of multiple SELECT statements in a stored procedure

I have a stored procedure where I need to run three separate SELECT statements and store the result in a variable.
I tried something like this:
SELECT #tier1MenuIds = Id
FROM TheGateKeeper.NavigationTier1
WHERE ([Page Name] = #currentSlug)
SELECT #tier2MenuIds = Id
FROM TheGateKeeper.NavigationTier2
WHERE ([Page Name] = #currentSlug)
SELECT #tier3MenuIds = Id
FROM TheGateKeeper.NavigationTier3
WHERE ([Page Name] = #currentSlug)
But it gives me an error saying
Incorrect syntax near '('.
The statement works if I remove the bottom two SELECTs. Any other options?
Edit: I am using SQL Server. Here is the full code:
CREATE PROCEDURE [TheGateKeeper].[editContent]
#description nvarchar(300),
#content nvarchar(MAX),
#title nvarchar(50),
#dateModified date,
#headerImageName nvarchar(100),
#slug nvarchar(50),
#id int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #currentSlug as nvarchar(100);
DECLARE #tier1MenuIds as int;
DECLARE #tier2MenuIds as int;
DECLARE #tier3MenuIds as int;
/* Check if the post exists */
SELECT #currentSlug = Slug
FROM TheGateKeeper.Posts
WHERE (Id = #id)
IF (##ROWCOUNT = 1)
BEGIN
/* Temporarily unlink all menu items linking to post */
SELECT #tier1MenuIds = Id
FROM TheGateKeeper.NavigationTier1
WHERE ([Page Name] = #currentSlug)
SELECT #tier2MenuIds = Id
FROM TheGateKeeper.NavigationTier2
WHERE ([Page Name] = #currentSlug)
SELECT #tier3MenuIds = Id
FROM TheGateKeeper.NavigationTier3
WHERE ([Page Name] = #currentSlug)
/* Update the post in the database */
UPDATE Posts
SET (Description = #description, [Content] = #content, Title = #title, [Date Modified] =#dateModified, HeaderImageName = #headerImageName, slug =#slug)
WHERE id = #id
RETURN 1
END
ELSE
BEGIN
RETURN 0
END
Remove the parentheses from your UPDATE statement; they are unnecessary.
Your update statement should be:
UPDATE Posts
SET Description = #description, [Content] = #content, Title = #title,
[Date Modified] =#dateModified, HeaderImageName = #headerImageName,
slug =#slug
WHERE id = #id