SQL server, concat nvarchar when some are null - sql

Probably a question of null values...
I would like to do just like in C# :
string s3 = s2 + ' ' + s1;
witch could be read like :
'hello world' = 'hello' + ' ' + 'world
But in SQL, some of my NVARCHAR(1) are null, so it sometimes look like :
null = 'hello + ' ' + null
And in this case i would rather have :
'hello ' = 'hello' + ' ' + null
I don't see, is there a simple way to do that ?

Use COALESCE() or ISNULL():
SELECT COALESCE(S2, '') + ' ' + COALESCE(S1, '')
Or:
SELECT ISNULL(S2, '') + ' ' + ISNULL(S1, '')

You can also use IIF() function or else CASE Statement
SELECT IIF(s2 IS NULL, '', s2) + ' ' + IIF(s1 IS NULL, '', s1)

Related

SQL cannot convert an int to a varchar(15) value and throws: Conversion failed when converting the varchar value ' LBS' to data type int

I am working on a SQL project that is pulling data from many tables to list them out in an email body. In the body of my email, I am pulling int values that are throwing exceptions because the body needs to eventually be a nvarchar(max). Different types of conversion have not worked for me yet.
This is SQL running on Microsoft SQL Server Management Studio. I have tried leaving the int unconverted, and a few different conversion methods I have seen elsewhere.
In the examples, wtpc.Reg_No is a varchar and wtpc.Shipment_Net_Weight is an int.
'Body' =
...
+ 'Net: ' +
CASE
WHEN wtpc.Reg_No IS NOT NULL THEN wtpc.Shipment_Net_Weight
ELSE '0'
END
+ ' LBS'
+ 'Gross:
...
Results in: Conversion failed when converting the varchar value ' LBS' to data type int.
'Body' =
...
+ 'Net: ' +
CASE
WHEN wtpc.Reg_No IS NOT NULL THEN str(wtpc.Shipment_Net_Weight)
ELSE '0'
END
+ ' LBS'
+ 'Gross:
...
Results in: Error converting data type varchar to float.
'Body' =
...
+ 'Net: ' +
CASE
ELSE wtpc.Reg_No IS NOT NULL THEN
CONVERT(INT,
CASE
WHEN IsNumeric(CONVERT(VARCHAR(15), wtpc.Shipment_Net_Weight)) = 1
THEN CONVERT(VARCHAR(15),wtpc.Shipment_Net_Weight)
ELSE 0
END)
ELSE '0'
END
+ ' LBS'
+ 'Gross:
...
Results in: Conversion failed when converting the varchar value ' LBS' to data type int.
This is lifted from this StackOverflow Question
Here is a more complete view:
Declare #TempResults1 table(
ThisSubject nvarchar(max),
ThisTo nvarchar(max),
ThisCC nvarchar(max),
ThisBody nvarchar(max),
ThisBody2 nvarchar(max))
Insert into #TempResults1
Select
'Subject' =
isnull( #ShipmentNoString, '') + ' - ' + shpr.Last_Name + ', ' + shpr.First_Name + isnull(' - ' + #ModeString, '')
+ case
when cstm.broker_agent = -1 then ' - Foreign Port Agent Pre-Alert'
else ' - Port Agent Pre-Alert'
end,
... [To and CC are set here similiar to how the subject is set]
'Body' =
+ 'To: ' + vncb.Vendor_Name
+ 'Attn: ' +
case
when #GsaUsContact is not null then #GsaUsContact
else #GsaForContact
end
+ 'From: ' + usrs.Name
+ 'Date: ' + format(getdate(), 'ddMMyy')
... [More similar code]
+ 'Mode: ' + mode.Mode
+ 'Net: ' +
case
when wtpc.Reg_No is not null then CAST( wtpc.Shipment_Net_Weight AS varchar(15))
else '0'
end
+ ' LBS'
+ 'Gross: ' +
case
when wtpc.Reg_No is not null then CAST( wtpc.Shipment_Gross as varchar(15))
else '0'
end
+ ' 2LBS'
+ 'Cube: ' + isnull(wtpc.Shipment_CFT, '0') + ' CFT'
+ 'Pieces: ' +
case
when wtpc.Reg_No is not null then CAST(wtpc.Shipment_Piece_Count, varchar(15))
else '0'
end
+ ' PCS'
+ '<BR>'
+ 'OBL/AWB #: ' + asea.Mawb_Obl_No
...[More code like above with varchars]
+isnull('<b> Please send all correspondence to: ' + usrs.email + '.</b>', '')
,Body2 = null
Found the fix:
isnull( convert(varchar(50), wtpc.Shipment_Net_Weight), '')
There were no matching cases, but the errors didn't show this, kinda goofy! Thank you for all the help everyone!

CHARINDEX with integer

Hi I have a select which works great where I use CHARINDEX on a varchar column, but when I try it on a integer column I get the following error;
Argument data type int is invalid for argument 1 of charindex function.
Below I have listed both queries.
stremail is varchar
intEmployeeID in integer
**below returns results as aspected**
SELECT intEmployeeID
FROM [dbo].[tblEmployees]
WHERE CHARINDEX(',' + strEmail + ',', ',' + REPLACE('test#gmail.com, test2#gmail.com', ' ', '') + ',') > 0
**below I get an error if I'm trying to select on a integer column**
SELECT intEmployeeID
FROM [dbo].[tblEmployees]
WHERE CHARINDEX(',' + intEmployeeID + ',', ',' + REPLACE('1, 2', ' ', '') + ',') > 0
Any help would be most greatful.
SELECT intEmployeeID
FROM [dbo].[tblEmployees]
WHERE CHARINDEX(',' + cast(intEmployeeID as nvarchar(max)) + ',', ',' + REPLACE('1, 2', ' ', '') + ',') > 0
+ cast(intEmployeeID as varchar)+
Cast intEmployeeID as varchar
You have to explicitly convert the integer to a character string, otherwise it compiles the + operators as integer addition instead of string concatenation :
CHARINDEX(',' + CONVERT(VARCHAR(10),intEmployeeID) + ',', ',' + REPLACE('1, 2', ' ', '') + ',')

using sql - Is not null in a select statement

I can't seem to figure out how to use the opposite of isnull or ifnull statements in sql. I need to say if a.Error1 is not null -- then print the ' - ' and the + CHAR(13)+CHAR(10). Basically There should be no dash or no new line break if the a.Error1 comes back null. So print the information if the field isn't null.
select a. ....
' - ' + a.Error1 + CHAR(13)+CHAR(10) +
' - ' + a.Error2 + CHAR(13)+CHAR(10) +
' - ' + a.Error3 + CHAR(13)+CHAR(10) +
' - ' + a.Error4 + CHAR(13)+CHAR(10) +
' - ' + a.Error5 + CHAR(13)+CHAR(10) +
' - ' + a.Error6 as 'error_message'
...
from table1 a
For example if for a given record error1, 2 and 5 returned output I would like the output to be as follows:
- Error1: There was a ...
- Error2: ....
- Error5: The data was ...
If no errors existed for that row it should simply be an empty/null field.
You can use CASE:
SELECT a. ....
(CASE WHEN a.Error1 IS NOT NULL
THEN ' - ' + a.Error1 + CHAR(13)+CHAR(10)
ELSE ''
END) +
(CASE WHEN a.Error2 IS NOT NULL
THEN ' - ' + a.Error2 + CHAR(13)+CHAR(10)
ELSE ''
END) +
(CASE WHEN a.Error3 IS NOT NULL
THEN ' - ' + a.Error3 + CHAR(13)+CHAR(10)
ELSE ''
END) +
...etc
Yes! i know i'm like 5 years too late but i too enountered this problem.
It's weird how it doesn't exist some kind of !ISNULL() but whatever.
Try this for a cleaner code:
select a. ....
IIF(a.Error1 IS NOT NULL, ' - ' + a.Error1 + CHAR(13)+CHAR(10) , '') as Error1,
IIF(a.Error1 IS NOT NULL, ' - ' + a.Error1 + CHAR(13)+CHAR(10) , '') as Error2
from table1 a
Learn more about IIF() function : SQL Server IIF Function
The COALESCE function does what you want here. The result of COALESCE is the first NOT NULL value it is passed. Below we use '', which is distinct from NULL so that the outer + is always applied to NOT NULL strings.
e.g.
select a. ....
COALESCE( ' - ' + a.Error1 + CHAR(13)+CHAR(10), '' ) +
COALESCE( ' - ' + a.Error2 + CHAR(13)+CHAR(10), '' ) +
COALESCE( ' - ' + a.Error3 + CHAR(13)+CHAR(10), '' ) +
COALESCE( ' - ' + a.Error4 + CHAR(13)+CHAR(10), '' ) +
COALESCE( ' - ' + a.Error5 + CHAR(13)+CHAR(10), '' ) +
COALESCE( ' - ' + a.Error6 , '' ) as 'error_message'
...
from table1 a
SELECT (CASE WHEN a.Error1 IS NOT NULL
THEN ' - ' + a.Error1 + CHAR(13)+CHAR(10) +
ELSE a.Error1
END) +
(CASE WHEN a.Error2 IS NOT NULL
THEN ' - ' + a.Error2 + CHAR(13)+CHAR(10) +
ELSE a.Error2
END) +
.....etc

Arithmetic overflow error converting varchar to data type numeric

Hi i have a query below which creates insert script for me. the column TotalPremiumValue has datatype Decimal(5,2). when i execute my query i am getting the following error: Arithmetic overflow error converting varchar to data type numeric. can anybody help me?
SELECT 'IF NOT EXISTS(SELECT 1 FROM Lkup.TotalPremium WHERE [TotalPremiumValue]= '''+[TotalPremiumValue]+''')
INSERT INTO Lkup.TotalPremium ' +
'(' +
'[TotalPremiumValue],' +
'[EffectiveDate]' +
')' +
'VALUES (' +
CASE WHEN [TotalPremiumValue] IS NULL THEN 'NULL' ELSE CONVERT(VARCHAR(40), [TotalPremiumValue]) END + ', ' +
CASE WHEN [EffectiveDate] IS NULL THEN 'NULL' ELSE 'CONVERT(DATETIME, ' + master.sys.fn_varbintohexstr (CONVERT(BINARY(8), [EffectiveDate])) + ')' END + ', ' +
')'
FROM Lkup.TotalPremium
Thanks
Perhaps try recasting the result as a decimal(5,2)? I added the call into a portion of your code and pasted the section below. You could also shrink that varchar(40) down to a varchar(6), which would hold all 5 numbers plus the decimal point.
'VALUES ( CAST(' +
CASE WHEN [TotalPremiumValue] IS NULL THEN 'NULL' ELSE CONVERT(VARCHAR(40), [TotalPremiumValue]) END + ' AS DECIMAL(5,2)), ' +
CASE WHEN [EffectiveDate] IS NULL THEN 'NULL' ELSE 'CONVERT(DATETIME, ' + master.sys.fn_varbintohexstr (CONVERT(BINARY(8), [EffectiveDate])) + ')' END + ', ' +
')'
Please try the below query
SELECT
'IF EXISTS(SELECT 1 FROM Lkup WHERE [TotalPremiumValue] = ' + CONVERT(varchar(50), [TotalPremiumValue]) + ')
INSERT INTO Lkup ' +
'(' +
'[TotalPremiumValue]' +
')' +
'VALUES (' +
case when CONVERT(varchar(50),[TotalPremiumValue]) IS NULL then 'null' else CONVERT(varchar(50),TotalPremiumValue) end +
')'
FROM Lkup

How to concatenate strings and commas in SQL Server?

I'm relatively new to MSSQL, so sorry if the question might sounds trivial. I want to concatenate multiple fields with a delimiter ,. However, when the field is empty, the extra , will be included in the result string as well. So is there an easy way to solve this problem? For example,
SELECT VRI.Street_Number_and_Modifier + ',' +
VRI.Street_Direction + ',' +
VRI.Street_Name + ',' +
VRI.Street_Direction + ',' +
VRI.Street_Suffix + ',' +
VRI.Street_Post_Direction + ',' +
VRI.Unit
FROM View_Report_Information_Tables VRI
This modified version of Lamak's handles NULL or strings containing only space/empty:
SELECT COALESCE(NULLIF(VRI.Street_Number_and_Modifier, '') + ',', '') +
COALESCE(NULLIF(VRI.Street_Direction, '') + ',', '') +
COALESCE(NULLIF(VRI.Street_Name, '') + ',', '') +
COALESCE(NULLIF(VRI.Street_Direction, '') + ',', '') +
COALESCE(NULLIF(VRI.Street_Suffix, '') + ',', '') +
COALESCE(NULLIF(VRI.Street_Post_Direction, '') + ',', '') +
COALESCE(NULLIF(VRI.Unit, ''), '')
FROM View_Report_Information_Tables VRI
I was able to get it to work with a slightly different approach. Putting the commas at the beginning of each field and then removing the first one with the STUFF function worked for me:
SELECT
STUFF((COALESCE(', ' + NULLIF(VRI.Street_Number_and_Modifier, ''), '') +
COALESCE(', ' + NULLIF(VRI.Street_Direction, ''), '') +
COALESCE(', ' + NULLIF(VRI.Street_Name, ''), '')) +
COALESCE(', ' + NULLIF(VRI.Street_Direction, ''), '')) +
COALESCE(', ' + NULLIF(VRI.Street_Suffix, ''), '')) +
COALESCE(', ' + NULLIF(VRI.Street_Post_Direction, ''), '')) +
COALESCE(', ' + NULLIF(VRI.Unit, ''), ''))
, 1, 2, '')
FROM View_Report_Information_Tables AS VRI
If the columns are empty instead of null, you can try this:
SELECT VRI.Street_Number_and_Modifier
+ CASE WHEN VRI.Street_Number_and_Modifier <> '' THEN ', ' ELSE '' END
+ VRI.Street_Direction
+ CASE WHEN VRI.Street_Direction <> '' THEN ', ' ELSE '' END
+ VRI.Street_Name
+ CASE WHEN VRI.Street_Name <> '' THEN ', ' ELSE '' END
+ VRI.Street_Direction
+ CASE WHEN VRI.Street_Direction <> '' THEN ', ' ELSE '' END
+ VRI.Street_Suffix
+ CASE WHEN VRI.Street_Suffix <> '' THEN ', ' ELSE '' END
+ VRI.Street_Post_Direction
+ CASE WHEN VRI.Street_Post_Direction <> '' THEN ', ' ELSE '' END
+ VRI.Unit
+ CASE WHEN VRI.Unit<> '' THEN ', ' ELSE '' END
FROM View_Report_Information_Tables VRI
For SQL 2008+
Using
ISNULL(Colmn1 + ', ', '')
Will always result with a leading comma in the end, so you'll have to handle it.
Example:
DECLARE #Column1 NVARCHAR(10) = 'Column1'
, #Column2 NVARCHAR(10) = 'Column2'
SELECT SUBSTRING( ISNULL(#Column1 + ', ', '') + ISNULL(#Column2 + ', ', '')
, 0 --Starting from 0 not 1 to remove leading comma
, LEN(ISNULL(#Column1 + ', ', '') + ISNULL(#Column2 + ', ', '')))
Or we could approach this the other way around and use the STUFF function to remove our beginning comma which looks cleaner, example:
SELECT STUFF (ISNULL(( ', ' + #Column1), '') + ISNULL(( ', ' + #Column2), ''), 1, 2, N'')
For SQL 2012+ we could use the CONCAT function and remove beginning comma using STUFF similar to our previous example but avoiding ISNULL:
SELECT STUFF(CONCAT( ', ' + #Column1, ', ' + #Column2), 1, 2, N'')
For SQL 2017+ CONCAT_WS was introduced where you can concatinate/join multiple string columns with a delimiter specified in the first argument of the function:
MS Documents CONCAT_WS
MS Doc Example:
SELECT CONCAT_WS(',' --delimiter
,'1 Microsoft Way', NULL, NULL, 'Redmond', 'WA', 98052) AS Address;
Try this:
SELECT COALESCE(VRI.Street_Number_and_Modifier + ',','') +
COALESCE(VRI.Street_Direction + ',','') +
COALESCE(VRI.Street_Name + ',','') +
COALESCE(VRI.Street_Direction + ',','') +
COALESCE(VRI.Street_Suffix + ',','') +
COALESCE(VRI.Street_Post_Direction + ',','') +
COALESCE(VRI.Unit,'')
FROM View_Report_Information_Tables VRI
Short or long answer?
Short answer - dont. This is a formatting issue, not a database issue.
Long answer - When you concatenate a string and a null in sql server, the result is null. So you can use combinations of ISNULL
SELECT ISNULL(afield + ',','') + ISNULL(bfield + ',','')
You have to use select case when IsNull(fieldname, '')= '' or ltrim(rtrim(fieldname))='') Then ... Else... end +...
Edit:
Was written from Android mobile.
Below your example.
The following translations (from German) apply, FYI:
Vorname: given name
Name: surname
Benutzer: User
And here's the example code:
CREATE VIEW [dbo].[V_RPT_SEL_Benutzer]
AS
SELECT
BE_ID AS RPT_UID,
CASE
WHEN (ISNULL(BE_Name, '0') = '0' OR LTRIM(RTRIM(BE_Name)) = '') AND (ISNULL(BE_Vorname, '0') = '0' OR LTRIM(RTRIM(BE_Vorname)) = '')
THEN ''
WHEN (ISNULL(BE_Name, '0') = '0' OR LTRIM(RTRIM(BE_Name)) = '')
THEN ISNULL(BE_Vorname, '')
WHEN (ISNULL(BE_Vorname, '0') = '0' OR LTRIM(RTRIM(BE_Vorname)) = '')
THEN ISNULL(BE_Name, '')
ELSE
ISNULL(BE_Name, '') + ', ' + ISNULL(BE_Vorname, '')
END AS RPT_Name,
ROW_NUMBER() OVER (ORDER BY BE_Name, BE_Vorname ASC) AS RPT_Sort
FROM T_Benutzer
You could use the ISNULL(field + ',', '')
SELECT isnull(VRI.Street_Number_and_Modifier + ',','')+
isnull(VRI.Street_Direction + ',','')+
isnull(VRI.Street_Name + ',','')+
isnull(VRI.Street_Direction + ',','')+
isnull(VRI.Street_Suffix + ',','')+
isnull(VRI.Street_Post_Direction + ',','')+
isnull(VRI.Unit,'')
FROM View_Report_Information_Tables VRI
I would agree completely with Jamiec's short answer.
Otherwise, I would look at a nasty solution of using a REPLACE([concat], ',,', ',') everywhere you concatenate two columns, and then figure out how to trim commas from the beginning and end of the string where the first and last columns might be empty. Very very messy.
Wanted to see if I can get it without using CASE but could not. A long-winded way of mine:
SELECT case when isnull(nullif(VRI.Street_Number_and_Modifier, ''),'')='' then '' else VRI.Street_Number_and_Modifier end
+ case when isnull(nullif(VRI.Street_Direction, ''),'')='' then '' else ',' + VRI.Street_Direction end
+ case when isnull(nullif(VRI.Street_Name, ''),'')='' then '' else ',' + VRI.Street_Name end
+ case when isnull(nullif(VRI.Street_Suffix, ''),'')='' then '' else ',' + VRI.Street_Suffix end
+ case when isnull(nullif(VRI.Street_Post_Direction, ''),'')='' then '' else ',' + VRI.Street_Post_Direction end
+ case when isnull(nullif(VRI.Street_Post_Direction, ''),'')='' then '' else ',' + VRI.Street_Post_Direction end
FROM View_Report_Information_Tables VRI
SELECT COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_1_TXT, ''), ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_2_TXT, '') , ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_3_TXT, '') , ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_CITY_TXT, '') , ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ST_TXT, '') , ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_CNTRY_TXT, '') , ',')+
COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_PSTL_CD, '') , '')
FROM ACCOUNT_DETAILS ad
This will not add any commas if null-strings
SELECT CONCAT_WS(', ', IFNULL(column1, NULL),
IFNULL(column2, NULL), IFNULL(column3, NULL),
IFNULL(column4, NULL), IFNULL(column5, NULL))
FROM yourtable