sybase ISNULL - are the conditions too long? - sql

I am trying to unmangle a very old variable. It was a full name entered all in one field and is found in two separate tables. In most newer places the name is in three logical columns, first, middle, last. In these it is all together and I am trying to strip it out to first initial, last name. I found the following here and modified it:
http://dbaspot.com/sqlserver-programming/365656-find-last-word-string.html
DECLARE #full_name VARCHAR(20)
DECLARE #fullname VARCHAR(20)
SELECT #full_name = REVERSE('John A Test')
SELECT #fullname = REVERSE('Joe Q Public')
SELECT #final = ISNULL(
(right(#full_name,1) + '. ' + (REVERSE(SUBSTRING(#full_name, 1,
CHARINDEX(' ',#full_name) - 1)))),
(right(#fullname,1) + '. ' + (REVERSE(SUBSTRING(#fullname, 1,
CHARINDEX(' ',#fullname) - 1 ))))
)
When I leave full_name there it works fine...returns J. Test. When I null it the default should be
J. Public but instead ends up as .. When I test each line separately they work. I tried COALESCE as well with the same results. Is this too many brackets for ISNULL or ????

You have problem with right(#full_name,1) + '. ', for example:
select null+'.'
gives you ..
Try to change your code using case as below:
DECLARE #full_name VARCHAR(20)
DECLARE #fullname VARCHAR(20)
DECLARE #final VARCHAR(20)
SELECT #full_name = null--REVERSE('John A Test')
SELECT #fullname = REVERSE('Joe Q Public')
SELECT #final = case
when #full_name is not null
then (right(#full_name,1) + '. ' + (REVERSE(SUBSTRING(#full_name, 1,
CHARINDEX(' ',#full_name) - 1))))
else (right(#fullname,1) + '. ' + (REVERSE(SUBSTRING(#fullname, 1,
CHARINDEX(' ',#fullname) - 1 ))))
end
select #final

Related

concat two columns in sql

I have four columns on data gridview and want them to concat in sql and exporting it to txt file but everytime i export this is my result.
My result
0010000 01500 00000 0001600
output required
001000001500000000001600
SQL Query:
string stringSql = " SELECT distinct " +
"REPLACE(RIGHT('00'+CAST(CAST(bat.PCN_Charge* 100.00 AS INT) AS VARCHAR(5)),8) as CLAIMAMT, + RIGHT('0'+CAST(CAST([CFee] * 100 AS INT) AS VARCHAR(5)),5),' ','' )as CFEE," +
"REPLACE(RIGHT('00000'+CAST(CAST([Solictors Fees] AS INT) AS VARCHAR(5)),5), + RIGHT('000'+CAST(CAST(bat.PCN_Charge + [CFee]*100 AS INT) AS VARCHAR(5)),9),' ','') as TotalAMT " +
Judging from the manual:
Method 1: Concatenating two strings
SELECT 'FirstName' + ' ' + 'LastName' AS FullName
Method 2: Concatenating two Numbers
SELECT CAST(1 AS VARCHAR(10)) + ' ' + CAST(2 AS VARCHAR(10))
Method 3: Concatenating values of table columns
SELECT FirstName + ' ' + LastName
FROM AdventureWorks.Person.Contact
In your case, you should do the same, avoiding the space in between.
select first_column+' '+second_c+' '+third_c+' '+forth_c
from table_name
try it
declare #result varchar(500)
set #result = ''
select #result = #result +' '+first_c+' '+second_c+' '+third_c+' '+forth_c
from table_name
declare #a varchar(50)
set #a='0010000 01500 00000 0001600'
select replace(#a,' ','')
SEE DEMO

Trouble extracting First and LastName from Full Name column

I am having FullName column and I am extracting the First Name and last name using the following query
select SUBSTRING(FULL_NAME, 1, CHARINDEX(' ', FULL_NAME) - 1) AS FirstName,
SUBSTRING(FULL_NAME, CHARINDEX(' ', FULL_NAME) + 1, 500) AS LastName
from [dbo].[TABLE]
But in the Full Name column there are just First names, some 10 digit phone numbers, 4 digit extensions and some text like 'this is a special case'.
How should I modify my query to accommodate these exceptions? And also when there are only single words in the Full Name column I am getting this following error message:
"Invalid length parameter passed to the LEFT or SUBSTRING function."
Parsing good names from free form fields is not an easy task...
I would suggest a dual approach.
Identify common patterns, i.e. you might find phone number with something like this
Where IsNumeric( Replace(Field,'-','')=1
and you might identify single names with
Where charindex(' ',trim(field))=0
etc.
Once you've identified them, the write code to attempt to split them...
So you might use the code you have above with the following WHERE clause
select SUBSTRING(FULL_NAME, 1, CHARINDEX(' ', FULL_NAME) - 1) AS FirstName,
SUBSTRING(PRQ_BP_CONTACT_NAME, CHARINDEX(' ', FULL_NAME) + 1, 500)
AS LastN
from [dbo].[TABLE]
where charindex(' ',trim(field))>0 and Where IsNumeric( Replace(Field,'-','')=0
Use the WHERE clauses to (a) make sure you only get records you can parse and (b) help identify the oddball cases you'll like need to do by hand...
Good luck
You could go with a function this allows you to put in any logic you need in the transform and keep things a bit more readable :
create function dbo.namepart( #fullname varchar(50), #part varchar(5))
returns varchar(10)
as
begin
declare #first varchar(50)
declare #last varchar(50)
declare #sp int
if #fullname like '%special value%' return ''
if #fullname like '% %'
begin
set #sp = CHARINDEX(' ', #fullname)
set #first = left(#fullname, #sp - 1)
set #last = substring(#fullname,#sp + 1 ,50)
if isnumeric(#last) <> 0 set #last = ''
end
else
begin
set #first = #fullname
set #last = ''
end
if #part like 'f%'
return #first
else
return #last
return ''
end
Sample data
create table blah(
full_name varchar(50)
)
insert into blah values ( 'john smith' ), ('paul 12345'),('evan'),('special value')
And see if it works
select
dbo.namepart(full_name,'first') first,
dbo.namepart(full_name,'last') last,
full_name
from blah
http://sqlfiddle.com/#!6/eb28f/2

Why does SQL Server conversion to bigint cause an error?

I am trying to convert varchar to bigint:
select convert(bigint, (select(Replace((select value from sometable), ' ', ''))))
Why is it giving error???
Error converting data type varchar to bigint.
thanks in advance
Update
This is part of query I am trying:
select top 1 *
into #tblTemp
from testTable
where Status = 0
order by Sno
declare #mobile varchar(50)
set #mobile = (select(Replace((select mobile from #tblTemp), ' ', '')))
--set #mobile = (select( Replace(' 9428017524', ' ', '')))
select convert(bigint, #mobile)
drop table #tblTemp
Try this
select convert(bigint, CASE WHEN ISNUMERIC(#mobile + 'e0') = 0
THEN 0 ELSE #mobile)
-- add this case statement to return only numeric values,
-- your query will fail for values like '123-415-6789', '(123)415-6789'
Check your mobile numbers data and see if there are any unexpected values in that column, you may have to replace '-' or '(' or ')' etc with ''.
SeLECT * FROM #tblTmp
WHERE ISNUMERIC(Replace(mobile, ' ', '') + 'e0') = 0;
I am not sure what your real string is but for safety you can check ISNUMERIC() before convertion.
DECLARE #mobile varchar(50)
SELECT #mobile = REPLACE(mobile, ' ','') --much simplified version
FROM #tblTemp
IF ISNUMERIC(#mobile)
SELECT CONVERT(bigint, #mobile)
ELSE
SELECT 0
Just by reading your queries, you don't need a temp table here at all. Everything can be done in a single query
SELECT TOP (1) CONVERT(bigint, CASE ISNUMERIC( REPLACE(mobile,' ','') )
WHEN 1 THEN REPLACE(mobile,' ','')
ELSE 0 END )
FROM testTable
WHERE Status = 0
ORDER By Sno

Get everything after and before certain character in SQL Server

I got the following entry in my database:
images/test.jpg
I want to trim the entry so I get: test
So basically, I want everything after / and before .
How can I solve it?
use the following function
left(#test, charindex('/', #test) - 1)
If you want to get this out of your table using SQL, take a look at the following functions that will help you: SUBSTRING and CHARINDEX. You can use those to trim your entries.
A possible query will look like this (where col is the name of the column that contains your image directories:
SELECT SUBSTRING(col, LEN(SUBSTRING(col, 0, LEN(col) - CHARINDEX ('/', col))) + 1,
LEN(col) - LEN(SUBSTRING(col, 0, LEN(col) - CHARINDEX ('/', col))) - LEN(SUBSTRING(
col, CHARINDEX ('.', col), LEN(col))));
Bit of an ugly beast. It also depends on the standard format of 'dir/name.ext'.
Edit:
This one (inspired by praveen) is more generic and deals with extensions of different length:
SELECT SUBSTRING(col, LEN(LEFT(col, CHARINDEX ('/', col))) + 1, LEN(col) - LEN(LEFT(col,
CHARINDEX ('/', col))) - LEN(RIGHT(col, LEN(col) - CHARINDEX ('.', col))) - 1);
Before
SELECT SUBSTRING(ParentBGBU,0,CHARINDEX('/',ParentBGBU,0)) FROM dbo.tblHCMMaster;
After
SELECT SUBSTRING(ParentBGBU,CHARINDEX('-',ParentBGBU)+1,LEN(ParentBGBU)) FROM dbo.tblHCMMaster
----select characters before / including /
select SUBSTRING ('abcde/wxyz',0,CHARINDEX('/','abcde/wxyz')+1)
--select characters after / including /
select SUBSTRING('abcde/wxyz',CHARINDEX('/','abcde/wxyz'),LEN('abcde/wxyz'))
declare #T table
(
Col varchar(20)
)
insert into #T
Select 'images/test1.jpg'
union all
Select 'images/test2.png'
union all
Select 'images/test3.jpg'
union all
Select 'images/test4.jpeg'
union all
Select 'images/test5.jpeg'
Select substring( LEFT(Col,charindex('.',Col)-1),charindex('/',Col)+1,len(LEFT(Col,charindex('.',Col)-1))-1 )
from #T
I have made a method which is much more general :
so :
DECLARE #a NVARCHAR(MAX)='images/test.jpg';
--Touch here
DECLARE #keysValueToSearch NVARCHAR(4000) = '/'
DECLARE #untilThisCharAppears NVARCHAR(4000) = '.'
DECLARE #keysValueToSearchPattern NVARCHAR(4000) = '%' + #keysValueToSearch + '%'
--Nothing to touch here
SELECT SUBSTRING(
#a,
PATINDEX(#keysValueToSearchPattern, #a) + LEN(#keysValueToSearch),
CHARINDEX(
#untilThisCharAppears,
#a,
PATINDEX(#keysValueToSearchPattern, #a) + LEN(#keysValueToSearch)
) -(PATINDEX(#keysValueToSearchPattern, #a) + LEN(#keysValueToSearch))
)
SELECT Substring('ravi1234#gmail.com', 1, ( Charindex('#', 'ravi1234#gmail.com')
- 1 ))
Before,
RIGHT('ravi123#gmail.com', ( Charindex('#', 'ravi123#gmail.com') + 1 ))
After
I just did this in one of my reports and it was very simple.
Try this:
=MID(Fields!.Value,8,4)
Note: This worked for me because the value I was trying to get was a constant not sure it what you are trying to get is a constant as well.
I know this has been a while.. but here is an idea
declare #test varchar(25) = 'images/test.jpg'
select
#test as column_name
, parsename(replace(#test,'/','.'),1) as jpg
,parsename(replace(#test,'/','.'),2) as test
,parsename(replace(#test,'/','.'),3) as images
I found Royi Namir's answer useful but expanded upon it to create it as a function. I renamed the variables to what made sense to me but you can translate them back easily enough, if desired.
Also, the code in Royi's answer already handled the case where the character being searched from does not exist (it starts from the beginning of the string), but I wanted to also handle cases where the character that is being searched to does not exist.
In that case it acts in a similar manner by starting from the searched from character and returning the rest of the characters to the end of the string.
CREATE FUNCTION [dbo].[getValueBetweenTwoStrings](#inputString
NVARCHAR(4000), #stringToSearchFrom NVARCHAR(4000), #stringToSearchTo
NVARCHAR(4000))
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE #retVal NVARCHAR(4000)
DECLARE #stringToSearchFromSearchPattern NVARCHAR(4000) = '%' +
#stringToSearchFrom + '%'
SELECT #retVal = SUBSTRING (
#inputString,
PATINDEX(#stringToSearchFromSearchPattern, #inputString) + LEN(#stringToSearchFrom),
(CASE
CHARINDEX(
#stringToSearchTo,
#inputString,
PATINDEX(#stringToSearchFromSearchPattern, #inputString) + LEN(#stringToSearchFrom))
WHEN
0
THEN
LEN(#inputString) + 1
ELSE
CHARINDEX(
#stringToSearchTo,
#inputString,
PATINDEX(#stringToSearchFromSearchPattern, #inputString) + LEN(#stringToSearchFrom))
END) - (PATINDEX(#stringToSearchFromSearchPattern, #inputString) + LEN(#stringToSearchFrom))
)
RETURN #retVal
END
Usage:
SELECT dbo.getValueBetweenTwoStrings('images/test.jpg','/','.') AS MyResult
I got some invalid length errors. So i made this function, this should not give any length problems. Also when you do not find the searched text it will return a NULL.
CREATE FUNCTION [FN].[SearchTextGetBetweenStartAndStop](#string varchar(max),#SearchStringToStart varchar(max),#SearchStringToStop varchar(max))
RETURNS varchar(max)
BEGIN
SET #string = CASE
WHEN CHARINDEX(#SearchStringToStart,#string) = 0
OR CHARINDEX(#SearchStringToStop,RIGHT(#string,LEN(#string) - CHARINDEX(#SearchStringToStart,#string) + 1 - LEN(#SearchStringToStart))) = 0
THEN NULL
ELSE SUBSTRING(#string
,CHARINDEX(#SearchStringToStart,#string) + LEN(#SearchStringToStart) + 1
,(CHARINDEX(#SearchStringToStop,RIGHT(#string,LEN(#string) - CHARINDEX(#SearchStringToStart,#string) + 1 - LEN(#SearchStringToStart)))-2)
)
END
RETURN #string
END
if Input= pg102a-wlc01s.png.intel.com and Output should be pg102a-wlc01s
we can use below query :
select Substring(pc.name,0,charindex('.',pc.name,0)),pc.name from tbl_name pc
You can try this:
Declare #test varchar(100)='images/test.jpg'
Select REPLACE(RIGHT(#test,charindex('/',reverse(#test))-1),'.jpg','')
Below query gives you data before '-'
Ex- W12345A-4S
SELECT SUBSTRING(Column_Name,0, CHARINDEX('-',Column_Name)) as 'new_name'
from [abc].
Output - W12345A
Inspired by the work of Josien, I wondered about a simplification.
Would this also work? Much shorter:
SELECT SUBSTRING(col, CHARINDEX ('/', col) + 1, CHARINDEX ('.', col) - CHARINDEX ('/', col) - 1);
(I can't test right now because of right issues at my company SQL server, which is a problem in its own right)
Simply Try With LEFT ,RIGHT ,CHARINDEX
select
LEFT((RIGHT(a.name,((CHARINDEX('/', name))+1))),((CHARINDEX('.', (RIGHT(a.name,
((CHARINDEX('/', name))+1)))))-1)) splitstring,
a.name
from
(select 'images/test.jpg' as name)a
declare #searchStart nvarchar(100) = 'search ';
declare #searchEnd nvarchar(100) = ' ';
declare #string nvarchar(4000) = 'This is a string to search (hello) in this text ';
declare #startIndex int = CHARINDEX(#searchStart, #string,0) + LEN(#searchStart);
declare #endIndex int = CHARINDEX(#searchEnd, #string, #startIndex + 1);
declare #length int = #endIndex - #startIndex;
declare #sub nvarchar(4000) = SUBSTRING(#string, #startIndex, #length)
select #startIndex, #endIndex, #length, #sub
This is a little more legible than the one-liners in this answer which specifically answer the question, but not in a generic way that would benefit all readers. This could easily be made into a function as well with a slight modification.
If there are more than one or none occurences of given character use this:
DECLARE #rightidx int = CASE
WHEN 'images/images/test.jpg' IS NULL OR (CHARINDEX('.', 'images/images/test.jpg')) <= 0 THEN LEN('images/images/test.jpg')
ELSE (CHARINDEX('.', REVERSE('images/images/test.jpg')) - 1)
END
SELECT RIGHT('images/images/test.jpg', #rightidx)
This was the approach I took.
CREATE FUNCTION dbo.get_text_before_char(#my_string nvarchar(255),#my_char char(1))
RETURNS nvarchar(255)
AS
BEGIN;
return IIF(#my_string LIKE '%' + #my_char + '%',left (#my_string, IIF(charindex(#my_char, #my_string) - 1<1,1,charindex(#my_char, #my_string) - 1)),'');
END;
CREATE FUNCTION dbo.get_text_after_char(#my_string nvarchar(255),#my_char char(1))
RETURNS nvarchar(255)
AS
BEGIN;
return IIF ( #my_string LIKE '%' + #my_char + '%' ,RIGHT ( #my_string , IIF ( charindex ( #my_char ,reverse(#my_string) )-1 < 1 ,1 ,charindex ( #my_char ,reverse(#my_string) )-1 ) ) , '' )
END;
SELECT
dbo.get_text_before_char('foo-bar','-')
, dbo.get_text_after_char('foo-bar','-')
declare #test varchar(100)='images/test.jpg'
select right(left(#test, charindex('.', #test) - 1),4)

How to get the nth string in any generic word or sentence with a space delimiter

How do I get the nth word in a sentence or a set of strings with space delimiter?
Sorry for the change in the requirement.Thank you.
By using instr.
select substr(help, 1, instr(help,' ') - 1)
from ( select 'hello my name is...' as help
from dual )
instr(help,' ') returns the positional index of the first occurrence of the second argument in the first, inclusive of the string you're searching for. i.e. the first occurrence of ' ' in the string 'hello my name is...' plus the space.
substr(help, 1, instr(help,' ') - 1) then takes the input string from the first character to the index indicated in instr(.... I then remove one so that the space isn't included..
For the nth occurrence just change this slightly:
instr(help,' ',1,n) is the nth occurrence of ' ' from the first character. You then need to find the positional index of the next index instr(help,' ',1,n + 1), lastly work out the difference between them so you know how far to go in your substr(.... As you're looking for the nth, when n is 1 this breaks down and you have to deal with it, like so:
select substr( help
, decode( n
, 1, 1
, instr(help, ' ', 1, n - 1) + 1
)
, decode( &1
, 1, instr(help, ' ', 1, n ) - 1
, instr(help, ' ', 1, n) - instr(help, ' ', 1, n - 1) - 1
)
)
from ( select 'hello my name is...' as help
from dual )
This will also break down at n. As you can see this is getting ridiculous so you might want to consider using regular expressions
select regexp_substr(help, '[^[:space:]]+', 1, n )
from ( select 'hello my name is...' as help
from dual )
Try this. An example of getting the 4th word:
select names from (
select
regexp_substr('I want my two dollars','[^ ]+', 1, level) as names,
rownum as nth
from dual
connect by regexp_substr('I want my two dollars', '[^ ]+', 1, level) is not null
)
where nth = 4;
The inner query is converting the space-delimited string into a set of rows. The outer query is grabbing the nth item from the set.
Try something like
WITH q AS (SELECT 'ABCD EFGH IJKL' AS A_STRING FROM DUAL)
SELECT SUBSTR(A_STRING, 1, INSTR(A_STRING, ' ')-1)
FROM q
Share and enjoy.
And here's the solution for the revised question:
WITH q AS (SELECT 'ABCD EFGH IJKL' AS A_STRING, 3 AS OCCURRENCE FROM DUAL)
SELECT SUBSTR(A_STRING,
CASE
WHEN OCCURRENCE=1 THEN 1
ELSE INSTR(A_STRING, ' ', 1, OCCURRENCE-1)+1
END,
CASE
WHEN INSTR(A_STRING, ' ', 1, OCCURRENCE) = 0 THEN LENGTH(A_STRING)
ELSE INSTR(A_STRING, ' ', 1, OCCURRENCE) - CASE
WHEN OCCURRENCE=1 THEN 0
ELSE INSTR(A_STRING, ' ', 1, OCCURRENCE-1)
END - 1
END)
FROM q;
Share and enjoy.
CREATE PROC spGetCharactersInAStrings
(
#S VARCHAR(100) = '^1402 WSN NI^AMLAB^tev^e^^rtS htimS 0055518',
#Char VARCHAR(100) = '8'
)
AS
-- exec spGetCharactersInAStrings '^1402 WSN NI^AMLAB^tev^e^^rtS htimS 0055518', '5'
BEGIN
DECLARE #i INT = 1,
#c INT,
#pos INT = 0,
#NewStr VARCHAR(100),
#sql NVARCHAR(100),
#ParmDefinition nvarchar(500) = N'#retvalOUT int OUTPUT'
DECLARE #D TABLE
(
ID INT IDENTITY(1, 1),
String VARCHAR(100),
Position INT
)
SELECT #c = LEN(#S), #NewStr = #S
WHILE #i <= #c
BEGIN
SET #sql = ''
SET #sql = ' SELECT #retvalOUT = CHARINDEX(''' + + #Char + ''',''' + #NewStr + ''')'
EXEC sp_executesql #sql, #ParmDefinition, #retvalOUT=#i OUTPUT;
IF #i > 0
BEGIN
set #pos = #pos + #i
SELECT #NewStr = SUBSTRING(#NewStr, #i + 1, LEN(#S))
--SELECT #NewStr '#NewStr', #Char '#Char', #pos '#pos', #sql '#sql'
--SELECT #NewStr '#NewStr', #pos '#pos'
INSERT INTO #D
SELECT #NewStr, #pos
SET #i = #i + 1
END
ELSE
BREAK
END
SELECT * FROM #D
END
If you're using MySQL and cannot use the instr function that accepts four parameters or regexp_substr, you can do this way:
select substring_index(substring_index(help, ' ', 2), ' ', -1)
from (select 'hello my name is...' as help) h
Result: "my".
Replace "2" in the code above with the number of the word you want.
If you are using SQL Server 2016+ then you can take advantage of the STRING_SPLIT function. It returns rows of string values and if you aim to get nth value, then you can use Row_Number() window function.
Here there is a little trick as you don't want to really order by something so that you have to "cheat" the row_number function and allow its value in the natural order which is the STRING_SPLIT() function will spit out.
Below is a code snippet if you want to find the third word of the string
Declare #_intPart INT = 3; -- change nth work here, start # from 1 not 0
SELECT value FROM(
SELECT value,
ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS rowno
FROM STRING_SPLIT('hello world this is amazing', ' ')
) AS o1 WHERE o1.rowno = #_intPart;
You can also make a scalar function to retrieve values.