SQL Server varchar to datetime - sql-server

I have a field varchar(14) = 20090226115644
I need convert it to -> 2009-02-26 11:56:44 (datetime format)
My idea. use cast and convert.. but I always have errors.
Conversion failed when converting
datetime from character string.
I made this, but don`t like it..
SELECT
SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2) as new --
FROM [Test].[dbo].[container_events]
where move IS not null
Result :2009-02-26 11:56:44

The CAST operator in SQL Server has a well-defined list of formats which are supported - see on MSDN SQL Server Books Online.
Your format doesn't seem to fit any of those defined formats -> you're on your own, you have to use some custom logic (as you do) to bring that varchar field into a format that CAST can understand.
So what is your question now??

your logic looks correct and works for the given data. however, I'll bet that you have some bad data out there.
try this:
DECLARE #container_events table (PK int, move varchar(14))
SET NOCOUNT ON
INSERT INTO #container_events VALUES (1,'20090226115644')
INSERT INTO #container_events VALUES (2,'20090226116644')
INSERT INTO #container_events VALUES (3,'20090227010203')
INSERT INTO #container_events VALUES (4,'20090228010203')
INSERT INTO #container_events VALUES (5,'20090229010203')
SET NOCOUNT OFF
---list all bad dates
SELECT
SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2) as BadDatesOnly, move
FROM #container_events
where ISDATE(SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2))=0
---list all bad dates
SELECT
CONVERT(datetime,SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2)) as GoodDatesOnly, move
FROM #container_events
where ISDATE(SUBSTRING(move,1,4) + '-' + SUBSTRING(move,5,2) + '-' + SUBSTRING(move,7,2) + ' ' + SUBSTRING(move,9,2) + ':' + SUBSTRING(move,11,2) + ':'+SUBSTRING(move,13,2))=1
OUTPUT:
BadDatesOnly move
------------------- --------------
2009-02-26 11:66:44 20090226116644
2009-02-29 01:02:03 20090229010203
(2 row(s) affected)
GoodDatesOnly move
----------------------- --------------
2009-02-26 11:56:44.000 20090226115644
2009-02-27 01:02:03.000 20090227010203
2009-02-28 01:02:03.000 20090228010203
(3 row(s) affected)
Using the ISDATE (Transact-SQL) function you can determine if the date is valid or not. AS a result you can filter out the bad rows in your query, or find the bad rows and fix them, etc. it is up to you what to do with the bad data.

Related

How to add query result single column to different table?

As you know with AS statement we can create a single column including query expressions. How can I add this single column to my table?
For example:
select
CAST(idwYear AS varchar(20)) + '-' +
CAST((right('00' + ltrim(str(idwMonth)), 2)) AS varchar(20)) + '-' +
CAST(right('00' + ltrim(str(idwDay)), 2) AS varchar(20)) AS finaldate
Now, how can I add final date to for example my_table?
That's the solution.
insert into finaldate
select
CAST(idwYear AS varchar(20)) + '-' +
CAST((right('00' + ltrim(str(idwMonth)), 2)) as varchar(20)) + '-' +
CAST(right('00' + ltrim(str(idwDay)), 2) AS varchar(20))
from
database.dbo.rawdata
why I cant do is I added values but no need to values statement
You can add finaldate as a computed column to the table using the DDL below:
ALTER TABLE dbo.my_table
ADD finaldate AS
CAST(idwYear AS varchar(20)) + '-'
+ CAST((right('00' + LTRIM(STR(idwMonth)), 2)) AS varchar(20)) + '-'
+ CAST(right('00' + LTRIM(STR(idwDay)), 2) AS varchar(20));

Conversion error in SQL Server

I have the following SQL query that gets a date (one parameter of start date and end date separated by a comma) as a parameter and should returns all values between these dates.
(Long query - I'm posting just the relevant part)
Set #SQLQuery = #SQLQuery + 'And (o.Date >= LEFT(''' + #Date + ''', charindex('','',''' + #Date+ ''') - 1)'
+ ' AND o.Date <= RIGHT(''' + #Date + ''', charindex('','',''' + #Date+ ''') - 1)) '
The format of the date parameter is:
start date,end date in MM,DD,YYYY format
When the date parameter is for example: 8-5-2015,08-9-2016 it's working perfectly, but when it is for example 8-5-2015,08-11-2016 I'm getting the following error:
Conversion failed when converting date and/or time from character
string
I think it's related to the two digits on the days part.
Any idea what can causes that?
It seems to be problem with logic inside Right function. Please use below logic , i have added length function to find right date correctly.
Set #SQLQuery = #SQLQuery + 'And (o.Date >= LEFT(''' + #Date + ''', charindex('','',''' + #Date+ ''') - 1)'
+ ' AND o.Date <= RIGHT(''' + #Date + ''', len(''' + #Date+ ''') - charindex('','',''' + #Date+ '''))) '
change the query to following type:
Set #SQLQuery = #SQLQuery + 'And (o.Date >= LEFT(''' + #Date + ''', charindex('','',''' + #Date+ ''') - 1)'
+ ' AND o.Date <= RIGHT(''' + #Date + ''', LEN(''' + #Date+ ''') - charindex('','',''' + #Date+ '''))) '

SQL syntax error with dynamically constructed INSERT?

I get the below error
An explicit value for the identity column in table 'c365online_script1.dbo.tProperty' can only be specified when a column list is used and IDENTITY_INSERT is ON.
The problem is with the statement that is dynamically constructed inside the two nested cursors from what I gather it should look something like
INSERT INTO dbo.Table(col1, col2, ...., colN) VALUES(Val1, val2, ...., ValN)
I am however unsure how I would construct the BELOW INSERT statement to resemble the above?.
EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + ' SELECT * FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id)
SET #Counter = 1 -- set the counter to make sure we execute loop only once.
END
You need to specify the list of columns because you don't insert into all of them (you don't insert into identity column). I'm guessing you're inserting from a table with the same structure from a different database - you need to specify all the source columns too in this case.
Your query will be (edit the column names):
EXEC('INSERT INTO ' + #Destination_Database_Name + '.dbo.' + #tablename + '(col1, col2, col3) SELECT col1, col2, col3 FROM ' + #Source_Database_Name + '.dbo.' + #tablename + ' WHERE ' + #Source_Database_Name + '.dbo.' + #tablename + '.CompanyID = ' + #Company_Id)

Insert vs Update

I have a table where all the fields are declared as nvarchar. If I do an insert into the table all unicode characters come into the fields fine. But when I do an update I am losing some of the characters. Here is my udpate statement:
UPDATE TableII
SET LOCATION = CAST(( COALESCE([CITY], N'') + NCHAR(13) + NCHAR(10)
+ COALESCE([INSTALLATION], N'') + NCHAR(13)
+ NCHAR(10) + LEFT(LOCATION.LATLONG, 2) + N'°'
+ SUBSTRING(LOCATION.LATLONG, 3, 2) + N''''
+ SUBSTRING(LOCATION.LATLONG, 5, 2) + NCHAR(34)
+ N' ' + SUBSTRING(LOCATION.LATLONG, 7, 1)
+ N' ' + SUBSTRING(LOCATION.LATLONG, 8, 3)
+ N'°' + SUBSTRING(LOCATION.LATLONG, 11, 2)
+ N'''' + SUBSTRING(LOCATION.LATLONG, 13, 2)
+ NCHAR(34) + N' ' + SUBSTRING(LOCATION.LATLONG,
15, 1) ) AS NVARCHAR(MAX))
FROM TABLEII
INNER JOIN LOC ON TABLEII.REC = LOC.REC
INNER JOIN LOCATION ON LOC.LOCRECNUM = LOCATION.LOCRECNUM
WHERE ( LOC.LOCSEQ = '1' )
As you can see I have tried a variety of things to force the unicode characters to not be lost, but it does not work.
Any ideas why the insert works fine but this update does not?
Is the City column NVARCHAR? If not, the COALESCE will take that column as it's data type and use it, regardless of what you do with the rest of the code.

SQL Server : execute dynamic sql help please

EXEC SP_EXECUTESQL
#DynamicSQL
, N'#HostIDs VARCHAR(MAX) OUTPUT'
, #HostIDs OUTPUT;
PRINT #HostIDs;
SELECT #HostIDs AS HostIDs;
SET #UpdateSQL = '
EXECUTE [dbo].[usp_Win7_HostUpdater_NEW]
#HostID = ''' + #HostIDs + ''' ,
#PackageID = ''' + #PackageID + ''' ,
#MigrationFlag = ''' + #MigrationFlagID + ''' ,
#Manufacturer = ' + #Manufacturer + ' ,
#Product = ' + #Product + ' ,
#Version = ' + #Version + ' ,
#Reason = ' + #Reason + ' ,
#Contact = ' + #Contact + '
';
SELECT #UpdateSQL AS UpdateSQL;
PRINT #UpdateSQL;
EXEC( #UpdateSQL )
END
I have a stored procedure on both a SQL Server 2005 and 2008 in which the above code is the last part of
it returns a VARCHAR(MAX) of numbers separated by commas.
Now this returned value is large upwards of 600k characters. If I execute this on a SQL Server 2005 it works like 50% of the time, #HostIDs is populated always and #UpdateSQL gets generated with the correct values and is executed.
On SQL Server 2008, #HostIDs is populated but #UpdateSQL is always NULL
This is weirding me out tremendously
Can anyone maybe shed some light on my odd problem?
Check these out
SET CONCAT_NULL_YIELDS_NULL OFF
select 'abc' + null + 'def'
--- abcdef
SET CONCAT_NULL_YIELDS_NULL ON
select 'abc' + null + 'def'
--- NULL
That's one way to get around the problem, which is to set it off before your string building and back on after. Any NULL in the sequence of string concatenation renders the entire statement NULL, which explains it works like 50% of the time - these are when all of the variables are non-null.
Completely agree with freefaller though, unless the question's an abstraction of a larger puzzle, there's no reason to build a dynamic SQL and EXEC it when a direct execution will work for the particular snippet shown.
If any of the parameters are null, the entire statement will be null. You can work around it by doing something like this (and I don't know what the data types are, but sometimes you need to cast them to varchar from int/bool/etc. types to make the concatenation work):
SET #UpdateSQL = '
EXECUTE [dbo].[usp_Win7_HostUpdater_NEW]
#HostID = ' + ISNULL('''' + #HostIDs + '''', 'null') + ' ,
#PackageID = ' + ISNULL('''' + #PackageID + '''', 'null') + ' ,
#MigrationFlag = ' + ISNULL('''' + #MigrationFlagID + '''', 'null') + ' ,
#Manufacturer = ' + ISNULL(#Manufacturer, 'null') + ' ,
#Product = ' + ISNULL(#Product, 'null') + ' ,
#Version = ' + ISNULL(#Version, 'null') + ' ,
#Reason = ' + ISNULL(#Reason, 'null') + ' ,
#Contact = ' + ISNULL(#Contact, 'null') + '
';
It causes because you are not handling nulls
you can use sp_executesql instead of exec it has some benefits over exec

Resources