Add number + varchar to get string concatenation - sql

How can I add 5596 + 00003 to get 559600003 in SQL Server?
I tried with the following query:
select 5596 + '00003'
But it is giving 5599 and I want this to show 559600003.

You can also use CONCAT():
SELECT CONCAT(5596, '00003')
CONCAT() does not require any explicit conversion.

SQL Server attempts to return the result in the datatype of the first part of the calculation which in your case is a number. It can happily convert the second part of the calculation into a number, and therefore does so.
To obtain the result you want you must convert the first part of the calculation to a string e.g.
select convert(varchar, 5596) + '00003'
Note: convert(varchar,x) uses a default length of 30 which is probably enough for most numbers.
CONCAT(), as in one of the other answers is probably a better solution.

You can use CAST
SELECT CAST(5596 AS varchar) + '00003'; -- return 559600003
Because :
CAST is more easier to read than CONVERT
CAST is ANSI-SQL compliant : it means that the CAST function can be used by many databases
But in case you have a date type CONVERT is more flexible and contains more options than CAST
For more details take a look : https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15

Related

How to find select conversion failed value

I have a query from core of data which is nvarchar and all values are '00:00:00' format. I want to convert it into long. When I try to convert top 1000 it working fine but problem with all values. Query show in below
SELECT DATEDIFF(second, '00:00', CAST(TimeSpent AS time(7)))* cast(1000 as bigint) + RIGHT(CAST(TimeSpent AS time(7)),7) FROM [mtr].[MatterDocument]
The error statement is
Conversion failed when converting date and/or time from character string
How can I find which value failed to convert?
I suggest that there is some bad data in your MatterDocument table. SQL Server does not support regex searches, but fortunately its LIKE operator does support some primitive regex which we can use:
SELECT *
FROM [mtr].[MatterDocument]
WHERE TimeSpent NOT LIKE '[01][0-9]:[0-5][0-9]:[0-5][0-9]' AND
TimeSpent NOT LIKE '2[0-3]:[0-5][0-9]:[0-5][0-9]';
Demo
You may verify in the demo that bad, non acceptable, time strings are being flushed out. The above query should also work to flush out strings which maybe aren't even time values at all, and somehow made it into your table.
The best long term fix would be to correct your data at its source, and then bring the data into SQL Server as a bona fide date/time type.
Edit: TRY_CAST, as described by #Denis in his answer, might be another approach. But this would require SQL Server 2012 or later. The above query should still work in earlier versions.
Try to use TRY_CAST function to find the wrong rows (it returns NULL if it cannot convert the value)
SELECT c.TimeSpent, /*Any columns to identify rows */
FROM (
SELECT TimeSpent, /*Any columns to identify rows */
DATEDIFF(second, '00:00', TRY_CAST(TimeSpent AS time(7)))* cast(1000 as bigint)
+ RIGHT(TRY_CAST(TimeSpent AS time(7)),7) AS Converted
FROM [mtr].[MatterDocument]
) c
WHERE Converted IS NULL
You should find the bad values:
select timespent
from t
where try_cast(TimeSpent AS time(7)) is null;
This will enable you to find the bad values. They are probably times that exceed 23.
I would suggest doing the conversion more simply:
select (left(TimeSpent, 2) * 60 * 60 +
substring(TimeStpent, 4, 2) * 60 +
right(TimeSpent, 2)
) as seconds
This will do the conversion without the limitations of the SQL Server time data type.

Oracle equivalent of NVL for number datatype

What is the Oracle equivalent of NVL for number datatypes?
This works since the datatype is VARCHAR:
select nvl(enrol.OUAC_APPLNO, 'blank') Invalid_OUAC_APPLNO
But this doesn't work since the datatype is NUMBER:
select nvl(enrol.ouac_type_id, 'blank') REGTYP
There is no equivalent and no Oracle functions will accept this (apart from DECODE() but don't do that); you're going to have to convert your number to a character:
select nvl(cast(enrol.OUAC_APPLNO as varchar2(10)), 'blank')
You may need to change the number of characters you're converting to as appropriate.
However, I don't know why you're doing this at all. By definition a NULL implies non-existence. If you want to display blank in order to confer non-existence this is something that you should be doing with your presentation layer rather than the database.
it wont work because oracle wants every row should be in the same type otherwise you cannot run functions on that column, you have cast ouac_type_id to be varchar as below;
select nvl(cast(enrol.OUAC_APPLNO as varchar2(10)), 'blank') REGTYP
select nvl(TO_CHAR(enrol.OUAC_APPLNO), 'blank') REGTYP

How do I combine three varchars variables from a database into a single variable in a SQL Command that is embedded at the top of Classic ASP page

For example, I'm trying to combine "String1" "String2" and "String3" to read as "String1 / String2 / String3". Then I'd like to convert that string to a date as each of my three string variables are month, day, and year saved separately.
I'm trying to do something like the following:
SELECT *, CONVERT(DATETIME, CONVERT(VARCHAR, month + "/" + day + "/" + year), 101) AS ActualDate
I actually have a functional page already connected to a database. I'm trying to add additional search features, and for that I need to be able to compare an actual date with search parameters when all I have are three varchars. What I'm looking for is how to convert those three varchars in to one string, and then convert that to a date in the SQL. The code example I used above does not work when added to the SQL statement. I don't' know if it's a simple syntax error, or if this isn't even the correct way to go about making the date.
In mysql try looking at the STR_TO_DATE() command. Also you have to use concat() in mysql you cannot use the + operand.
STR_TO_DATE(concat(month,'/',day,'/',year), '%m/%d/%Y')
EDIT:
If you are using sql server change the "/" to '/' in your original question and it will work.

Select data in date format

I have a query in which I want to select data from a column where the data is a date. The problem is that the data is a mix of text and dates.
This bit of SQL only returns the longest text field:
SELECT MAX(field_value)
Where the date does occur, it is always in the format xx/xx/xxxx
I'm trying to select the most recent date.
I'm using MS SQL.
Can anyone help?
Try this using ISDATE and CONVERT:
SELECT MAX(CONVERT(DateTime, MaybeDate))
FROM (
SELECT MaybeDate
FROM MyTable
WHERE ISDATE(MaybeDate) = 1) T
You could also use MAX(CAST(MaybeDate AS DateTime)). I got in the (maybe bad?) habit of using CONVERT years ago and have stuck with it.
To do this without a conversion error:
select max(case when isdate(col) = 1 then cast(col as date) end) -- or use convert()
from . . .
The SQL statement does not specify the order of operations. So, even including a where clause in a subquery will not guarantee that only dates get converted. In fact, the SQL Server optimizer is "smart" enough to do the conversion when the data is brought in and then do the filtering afterwards.
The only operation that guarantees sequencing of operations is the case statement, and there are even exceptions to that.
Another solution would be using PATINDEX in WHERE clause.
SELECT PATINDEX('[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]', field_value)
Problem with this approach is you really are not sure if something is date (e.g. 99/99/9999 is not date).
And problem with IS_DATE is it depends on configuration (e.g. DATEFORMAT).
So, use an appropriate option.

Easy way to force DATEPART to output as fixed-length?

When I do for example DATEPART(mm, GETDATE()) I get the result of the month being "8" for August. If i did the same thing in December I would get "12". Those are two different length results.
Is there a way to get the DATEPART results to always be a fixed length? So that for example the months would show up as 08 or 12. And days would be 05 and 30.
More Details:
I'm using a derived column transformation in SSIS to take a server datestamp, and remove all the formatting (spaces, colons, dashes, etc) in order to use it as part of a Primary Key.
My forumula that currently works is below, however it results in variable lenght results which is not ideal. I would like to get all results to be the same lenght.
((DT_STR,4,1252)DATEPART("yyyy",createDate)) + ((DT_STR,2,1252)DATEPART("mm",createDate)) + ((DT_STR,2,1252)DATEPART("dd",createDate)) + ((DT_STR,2,1252)DATEPART("hh",createDate)) + ((DT_STR,2,1252)DATEPART("mi",createDate)) + ((DT_STR,2,1252)DATEPART("ss",createDate)) + ((DT_STR,2,1252)DATEPART("ms",createDate))
Input looks like this:
9/11/2008 8:50:47:300 PM
Results look like:
20089112050473
Results should look like:
20080911205047300
SELECT RIGHT(100+DATEPART(mm, GETDATE()),2)
EDIT based on new info
- to get your timestamp to a fixed string of numbers:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(varchar(23), GETDATE(), 121),'-',''),':',''),' ',''),'.','')
The return type of DATEPART is int. The moment you ask for 05, is no longer and int but a string (char, varchar, nchar, nvarchar etc). As long as you understand the difference and you are OK with it, there are all sort of manipulations you can do to format the string as you whish, a good example being the one DJ showed. In truth though the proper place for such manipulations is on the client reporting, not on the server.
You can use CONVERT to grab a fixed-length date, for example:
SELECT CONVERT(nvarchar(30), GETDATE(), 126)
Which will show:
2006-04-18T09:58:04.570
which every variable in a fixed position.
Building on Andomar's example above:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(
CONVERT(nvarchar(30), GETDATE(), 126),'-',''),'.',''),':',''),'T','')
Which will show:
20060418095804570
Caution: using a timestamp as a primary key WILL eventually bite you in the butt. Also, a primary key that is a number will be faster than a long string like this, so consider changing your algorithm to use a numeric conversion of the timestamp rather than a string.
Solution #2 Use a .NET user-defined function that wraps DateTime.ToString() so you can pass a specific format ("yyyymmddHHMMss" or whatever). Given the number of casts and replacements, it's possible this might perform just as well as straight T-SQL.