Executing a function. Unable to print the output - sql

I recently came across the following FUNCTION in stackoverflow:
CREATE FUNCTION dbo.UrlDecode(#url varchar(3072))
RETURNS varchar(3072)
AS
BEGIN
DECLARE #count int, #c char(1), #cenc char(2), #i int, #urlReturn varchar(3072)
SET #count = Len(#url)
SET #i = 1
SET #urlReturn = ''
WHILE (#i <= #count)
BEGIN
SET #c = substring(#url, #i, 1)
IF #c LIKE '[!%]' ESCAPE '!'
BEGIN
SET #cenc = substring(#url, #i + 1, 2)
SET #c = CHAR(CASE WHEN SUBSTRING(#cenc, 1, 1) LIKE '[0-9]'
THEN CAST(SUBSTRING(#cenc, 1, 1) as int)
ELSE CAST(ASCII(UPPER(SUBSTRING(#cenc, 1, 1)))-55 as int)
END * 16 +
CASE WHEN SUBSTRING(#cenc, 2, 1) LIKE '[0-9]'
THEN CAST(SUBSTRING(#cenc, 2, 1) as int)
ELSE CAST(ASCII(UPPER(SUBSTRING(#cenc, 2, 1)))-55 as int)
END)
SET #urlReturn = #urlReturn + #c
SET #i = #i + 2
END
ELSE
BEGIN
SET #urlReturn = #urlReturn + #c
END
SET #i = #i +1
END
RETURN #urlReturn
END
GO
I am trying to pass the following URL as an input to get the decoded URL as output using the following command:
DECLARE #urlReturn nvarchar(3072);
EXEC dbo.UrlDecode2 #url = 'https%3a%2f%2fin.mathworks.com';
PRINT #urlReturn;
GO
Initially tried the following:
exec dbo.UrlDecode2 #url = 'https%3a%2f%2fin.mathworks.com';
go
The function decoded the encoded parts in the URL. I am totally new to PL/SQL. Could someone tell me where I am going wrong and how to print the decoded URL.

Declare #URL varchar(500)
Set #URL = dbo.UrlDecode2('https%3a%2f%2fin.mathworks.com')
Returns
https://in.mathworks.com
Or within a Select
Select URL = dbo.UrlDecode2('https%3a%2f%2fin.mathworks.com')

Related

Replace few keywords from SQL search result

A column with varchar string has been selected from a table.
There are some special characters that require to be replaced for displaying purpose.
What is the best way to do it?
select top (1) timestamp, url from dbo.transcationtable
and transaction table contains url which have %20, %22 etc for spaces and other characters.
Need to replace them with physical space and other symbol
You are looking for UrlDecode you can try to write a function.
CREATE FUNCTION dbo.UrlDecode(#url varchar(3072))
RETURNS varchar(3072)
AS
BEGIN
DECLARE #count int, #c char(1), #cenc char(2), #i int, #urlReturn varchar(3072)
SET #count = Len(#url)
SET #i = 1
SET #urlReturn = ''
WHILE (#i <= #count)
BEGIN
SET #c = substring(#url, #i, 1)
IF #c LIKE '[!%]' ESCAPE '!'
BEGIN
SET #cenc = substring(#url, #i + 1, 2)
SET #c = CHAR(CASE WHEN SUBSTRING(#cenc, 1, 1) LIKE '[0-9]'
THEN CAST(SUBSTRING(#cenc, 1, 1) as int)
ELSE CAST(ASCII(UPPER(SUBSTRING(#cenc, 1, 1)))-55 as int)
END * 16 +
CASE WHEN SUBSTRING(#cenc, 2, 1) LIKE '[0-9]'
THEN CAST(SUBSTRING(#cenc, 2, 1) as int)
ELSE CAST(ASCII(UPPER(SUBSTRING(#cenc, 2, 1)))-55 as int)
END)
SET #urlReturn = #urlReturn + #c
SET #i = #i + 2
END
ELSE
BEGIN
SET #urlReturn = #urlReturn + #c
END
SET #i = #i +1
END
RETURN #urlReturn
END
GO
use like
Select top (1) timestamp, UrlDecode(url) from dbo.transcationtable
sqlfiddle
Refer link:
http://sqlblog.com/blogs/peter_debetta/archive/2007/03/09/t-sql-urldecode.aspx

MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function

when i create a function in sql server 2012 , in this function
CREATE FUNCTION howords (#str nvarchar(50), #word nvarchar(50))
RETURNS int
AS
BEGIN
DECLARE #tempstr nvarchar(max)
DECLARE #space int
DECLARE #count int
DECLARE #size int
SET #count = 0
WHILE (LEN(#str) >= 0)
BEGIN
SET #space = CHARINDEX(' ', #str, 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = 0
WHILE (LEN(#str) > 0)
BEGIN
SET #space = CHARINDEX(' ', #str + 1)
SET #tempstr = LEFT(#str, (#space - 1))
IF (#tempstr = #word)
SET #count = #count + 1
SET #size = LEN(#tempstr)
IF (((LEN(#str)) - #space) > 0)
SET #str = SUBSTRING(#str, #space + 1, ((LEN(#str)) - #space))
IF (((LEN(#str)) - #space) <= 0)
BEGIN
IF (#str = #word)
SET #count = #count + 1
BREAK
END
END
END
END
RETURN #count
END
when i exec this query
select dbo.howords ('hello my hello','hello' )
i want to give me count (2)
but it give me an error
MSG 537 :Invalid length parameter passed to the LEFT or SUBSTRING function.
any help?
Try this
DECLARE #tosearch VARCHAR(MAX)='Hello'
DECLARE #string VARCHAR(MAX)='hello my hello'
SELECT (DATALENGTH(#string)-DATALENGTH(REPLACE(#string,#tosearch,'')))/DATALENGTH(#tosearch)
AS OccurrenceCount

SQL Server stored procedure: finding the values of Odd and even

I'm using #subno as Input. And I had to find the odd and even numbers. 16 is not a fix and it can be any other number. My question is how to find the odd and even number of my input?
Lastly, subno includes ( . ) dot at any position. e.g 123456.789123 I need to find the odd and even number of "123456" and the odd and even number of "789123" the dot ( . ) is the separator.
Once you find the odd for the left side, sum them up together. Once you find the even number for left side sum it up as well and then add the total odd to the total even values. That goes the same for the right side eg "789123".
Please help me. this is my 2nd week of trying to find the solution. Once you find all the total values for each side, multiply them together. example "123456" - total value of odd and even * the "789123" total value of odd and even.
It is for the the check digit validation. Validating the subscriber number. after validating through the calculation it should match the calculated reference number to the valid check digit number. It's the business rule. Kind of algorithm
create procedure ProcedureName
(#subno VARCHAR(16), --Input the 16 subscriber number
#result INT OUT,
)
as
begin
IF(LEN(#subno) <> 16)
SET #result = 1 -- INVALID RESULT
ELSE
IF(#subno % 2 = 0)
SET #result = #subno - even numbers
ELSE
SET #result = #subno --odd numbers
end
Please see below my sample work
-- this is the sample
create procedure ProcedureName
(
#subno VARCHAR(20), --Subscriber no
#result INT OUT, --result is invalid for 1, valid for 0
#payamt int
)
as
DECLARE #WA VARCHAR(2)
DECLARE #Weights varchar(9)
DECLARE #I INT
DECLARE #WD INT
DECLARE #WP INT
DECLARE #A INT
DECLARE #B INT
DECLARE #R INT
DECLARE #WR INT
SET #WR = 0
SET #R = 0
SET #A = 0
SET #B = 0
SET #WP = 0
SET #I = 0
BEGIN
IF (LEN(#subNo) = 7) AND (SUBSTRING(#subno,1,1) = '2') OR (SUBSTRING(#subno,1,1) = '9')
BEGIN
SET #result = 0 --VALID
END
ELSE IF(LEN(#subno) = 8) AND (SUBSTRING(#subno,1,1) = '2') OR
(SUBSTRING(#subno,1,1) = '9')
BEGIN
SET #result = 0 --VALID
END
ELSE IF(LEN(#subno) = 9)
BEGIN
SET #WA = SUBSTRING(#subno,1,2)
IF(#WA = '65')
set #result = 1 -- INVALID
else
BEGIN
SET #Weights = '12121212'
SET #WA = SUBSTRING(#subno,9,1)
SET #WD = 0
SET #I = 1
WHILE #I<9
BEGIN
SET #WP = cast(SUBSTRING(#Weights, #I,1)as int) * cast(SUBSTRING(#subno, #I, 1) as int)
IF(#WP > 9)
BEGIN
SET #A = SUBSTRING(CAST(#WP AS VARCHAR),1,1)
SET #B = SUBSTRING(CAST(#WP AS VARCHAR),2,1)
SET #WP = CAST(#A AS INT) + CAST(#B AS INT)
END
SET #WD = #WP + #WD
SET #I = #I + 1
END
SET #R = #WD % 10
IF(#R <> 0)
SET #WR = 10 - #R
ELSE
SET #WR = #R
IF(#WR <> CAST(#WA AS INT))
BEGIN
SET #result = 1 -- INVALID
END
ELSE
BEGIN
SET #result = 0 -- VALID
END
END
END
ELSE IF (LEN(#subno) = 10)
BEGIN
SET #I =1
SET #WD = 0
SET #Weights = '121212121'
SET #WA = SUBSTRING(#subno,10,1)
WHILE(#I < 10)
BEGIN
SET #WP = CAST(SUBSTRING(#Weights, #I, 1)AS INT) * CAST(SUBSTRING(#subno, #I, 1) AS INT)
IF(#WP > 9)
BEGIN
SET #A = SUBSTRING(CAST(#WP AS VARCHAR),1,1)
SET #B = SUBSTRING(CAST(#WP AS VARCHAR),2,1)
SET #WP = CAST(#A AS INT) + CAST(#B AS INT)
END
SET #WD = #WP + #WD
SET #I = #I + 1
END
SET #R = #WD % 10
IF(#R <> 0)
SET #WR = 10 - #R
ELSE
SET #WR = #R
IF (#WR<> #WA)
BEGIN
SET #result = 1 -- INVALID
END
ELSE
BEGIN
SET #result = 0 -- VALID
END
END
ELSE
SET #result = 1 -- INVALID
END
Split the values which u get . Then iterate iver each side and add them. Please see the sample below.
declare #v varchar (16) , #num1 varchar(20) , #num2 varchar(20)
set #v = '1234567.78906656'
select #num1 = substring(#v,0,charindex('.',#v))
select #num2 = substring(#v,charindex('.',#v)+1,len(#v))
--select #num1 = convert(int, substring(#v,0,charindex('.',#v)))
--select #num2 = substring(#v,charindex('.',#v)+1,len(#v))
declare #index int = 1 ,#len INT , #char CHAR
declare #TotalOddL int = 0
declare #TotalEvenL int = 0
DECLARE #FullTotL INT = 0
declare #TotalOddR int = 0
declare #TotalEvenR int = 0
DECLARE #FullTotR INT = 0
DECLARE #TEMP INT
set #len= LEN(#num1)
WHILE #index <= #len
BEGIN
set #char = SUBSTRING(#num1, #index, 1)
SET #TEMP = cast(#char as int)
IF(#TEMP % 2 = 0)
SET #TotalEvenL = #TotalEvenL + #char
else
SET #TotalOddL = #TotalOddL + #char
SET #FullTotL = #TotalEvenL + #TotalOddL
SET #index= #index+ 1
END
Select 'LeftSide total' , #FullTotL
Select 'Left Side odd' , #TotalOddL
Select 'Left Side Even' , #TotalEvenL
SET #index = 1
set #len= LEN(#num2)
WHILE #index <= #len
BEGIN
set #char = SUBSTRING(#num2, #index, 1)
SET #TEMP = cast(#char as int)
IF(#TEMP % 2 = 0)
SET #TotalEvenR= #TotalEvenR + #char
else
SET #TotalOddR = #TotalOddR + #char
SET #FullTotR = #TotalEvenR + #TotalOddR
SET #index= #index+ 1
END
select 'TotalRSide' , #FullTotR
select 'RsideOdd' , #TotalOddR
select 'RSideEven' , #TotalEvenR
select 'Multiplied value' , #FullTotR * #FullTotL
create or replace procedure prc_even_odd(i_number in number, o_result out varchar2)
as
begin
if (mod(i_number,2) = 0) then
o_result := 'EVEN';
else
o_result := 'ODD';
end prc_even;

Function to check the input number of words

Need help to create a function that returns TRUE or FALSE. TRUE - if type 1 or 3 words (like '__hello_', '_hello', '_hello my frend' - spaces should be cut), if the condition is not fulfilled FALSE
CREATE FUNCTION dbo.nazvFac(#f nvarchar(30))
RETURNS bit
AS
BEGIN
DECLARE #l int = 1, #s nvarchar(30), #i int = 0, #b bit
WHILE LTRIM(RTRIM(LEN(#f))) >= #l --error here, but I do not know how to fix it
BEGIN
SET #s = SUBSTRING(#f, #l, 1)
IF #s BETWEEN 'А' AND 'я'
SET #l += 1
ELSE IF #s = ' '
BEGIN
SET #l -= 1
SET #s = SUBSTRING(#f, #l, 1)
SET #s = RTRIM(#s)
SET #l += 2
SET #i += 1
END
ELSE
BREAK
END
IF #i = 0 OR #i = 2
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
GO
WHILE LTRIM(RTRIM(LEN(#f))) >= #l --error here, but I do not know how to fix it
LEN() returns an int, which you are then passing to a string function: RTRIM().
You want to return TRUE only if there are one or three words? This should do it:
CREATE FUNCTION dbo.nazvFac(#f NVARCHAR(30))
RETURNS BIT
AS
BEGIN
DECLARE #l INT, #b BIT
SET #l = LEN(#f) - LEN(REPLACE(#f, ' ', '')) + 1
IF #l == 1 OR #l == 3
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
Also, JC. is right about the len() error.
You should trim the string and then check the length.
CREATE FUNCTION dbo.nazvFac(#f NVARCHAR(30))
RETURNS BIT
AS
BEGIN
DECLARE #l INT = 1, #s NVARCHAR(30), #i INT = 0, #b BIT
WHILE LEN(LTRIM(RTRIM(#f))) >= #l --I think youn need to trim the string and then check length
BEGIN
SET #s = SUBSTRING(#f, #l, 1)
IF #s BETWEEN 'А' AND 'я'
SET #l += 1
ELSE IF #s = ' '
BEGIN
SET #l -= 1
SET #s = SUBSTRING(#f, #l, 1)
SET #s = RTRIM(#s)
SET #l += 2
SET #i += 1
END
ELSE
BREAK
END
IF #i = 0 OR #i = 2
SET #b = 'TRUE'
ELSE
SET #b = 'FALSE'
RETURN #b
END
GO

SQL code for anagram

I have a SQL code for finding whether two words are anagram or not.
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF (SELECT COUNT(*) FROM
(
select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0
UNION
select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0
)
t)
= LEN(#str1)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END
But for words like mmaa and mama this program returns not anagram. But they are anagrams. How can I solve this problem?
rather crude, but how about:
Declare #S1 varChar(100) = 'mmaa'
Declare #S2 varChar(100) = 'mama'
Declare #c char(1)
Declare #i tinyint
Declare #o1 varChar(100) = ''
Declare #o2 varChar(100) = ''
While DataLength(#s1) > 0 Begin
Set #c = Left(#s1, 1)
Set #s1 = Substring(#s1, 2, len(#s1))
Set #i = 1
While #i <= Len(#o1) And #c > substring(#o1, #i, 1) Set #i += 1
Set #o1 = left(#o1, #i-1) + #c + substring(#o1, #i, len(#o1))
End
While DataLength(#s2) > 0 Begin
Set #c = Left(#s2, 1)
Set #s2 = Substring(#s2, 2, len(#s2))
Set #i = 1
While #i <= Len(#o2) And #c > substring(#o2, #i, 1) Set #i += 1
Set #o2 = left(#o2, #i-1) + #c + substring(#o2, #i, len(#o2))
End
Select case When #o1 = #o2 Then 'Anagram' Else 'Not Anagram' End
or to encapsulate the sort into a function,
Create FUNCTION [dbo].[SortString](#s varChar(8000))
RETURNS varChar(8000)
As
Begin
Declare #c char(1)
Declare #i int
Declare #out varChar(8000) = left(#s, 1)
While DataLength(#s) > 0 Begin
Set #s = Substring(#s, 2, len(#s)-1)
Set #c = Left(#s, 1)
Set #i = 0
While #i < Len(#out) And #c > substring(#out, #i+1, 1) Set #i += 1
Set #out = case when #i < Len(#out)
then stuff(#out, #i+1, 0, #c)
else #out + #c end
End
return #out
End
Please try using CHECKSUM_AGG
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0)T1)=
(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0)T2)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END