How to copy data from one table to another where column data types are different? - sql

I have two tables.
NEW [contains data] [all columns are varchar]
NEW2 [empty table] [columns are of different data types]
I want to copy all data from New to New2.
What i did is,
SELECT T.*
INTO #tmp
FROM (SELECT *
FROM [dbo].[new]) AS T
then
INSERT INTO New2(col1, col2....)
SELECT *
FROM #TMP
But its not working.
Msg 242, Level 16, State 3, Line 2
The conversion of a varchar data type to a smalldatetime data type resulted in an out-of-range value.
The statement has been terminated.
[what I want is to change the column data types of NEW table, especially the varchar to smalldatetime. So I tried this way. Any other approach is also welcome.]
Any help would be greatly appreciated.
Thank You.

Yes. Done.
What I did is,
Imported Excle data in SQL Server table with all columns in a table as varchar data type.
The problem was in excel data, the date values, somewhere was NA. So I had to replace all those NA values with null.
To check for those invalid date values in a table, I used following command.
SELECT ISDATE(COL_NAME) AS Result
SELECT ISNULL(COL_NAME) AS Result
For this, sometime you have to also check & set for the date format of SQL Server using following commands,
DBCC useroptions
SET DATEFORMAT mdy
Then all the result values I replaced them with NULL as
UPDATE TABLE SET COLUMN = NULL WHERE ISDATE(COLUMN) = 0 OR COLUMN = 'NA'
At last I updated required columns manually using simple alter commands as,
ALTER TABLE ALTER COLUMN COL_NAME <<data type>>
I also changed my dateforamat to dmy which prior was mdy.
Thank for Suraj Singh, Deepshikha for their helpful suggestions.

While inserting cast your column to smalldatetime
SET DATEFORMAT ymd
INSERT INTO New2(col1, col2....)
SELECT Col1,Col2 , CAST('2007-05-08 12:35:29' AS smalldatetime) As Col_Name,...Col3
FROM #TMP

Try as:
DECLARE #NEW TABLE([date] VARCHAR(20));
INSERT #NEW SELECT '2/8/2013 15:00' ;
select LEFT([date],2) + SUBSTRING([date],3,2) + SUBSTRING([date],5,4) + ' '+ RIGHT([date],5)+':00'
from #NEW
UPDATE #NEW SET [date] = CONVERT(CHAR(16), CONVERT(SMALLDATETIME,
LEFT([date],2) + SUBSTRING([date],3,2) + SUBSTRING([date],5,4) + ' '+ RIGHT([date],5)+':00', 120));
SELECT [date], CONVERT(SMALLDATETIME, [date]) FROM #NEW;

Try This
SET DATEFORMAT ymd
INSERT INTO destination_table(column_name)
SELECT Column_name As Aliace_name
FROM Source_table

Related

UPDATE SET FORMAT not working in SQL Server 2016?

FORMAT instruction works in a SELECT but has no effect in an UPDATE:
SELECT ##VERSION
DROP TABLE IF EXISTS #t;
CREATE TABLE #t(DateMin datetime);
INSERT INTO #t VALUES ('2019-13-01 00:00:00')
SELECT * FROM #t
UPDATE #t SET DateMin = FORMAT(DateMin, 'dd/MM/yyyy');
SELECT * FROM #t;
SELECT #DateMin AS a, FORMAT(#DateMin, 'dd/MM/yyyy') AS b
A type like DATETIME isn't stored with a format.
So if one updates a DATETIME with a string in a certain format, it doesn't matter for the stored value in the DATETIME field.
The formatted string is implicitly converted to a datetime. At least if it's in a format that's valid.
The function FORMAT, which returns a NVARCHAR is rather used for representation of the datetime field in a query.
Or if one wants to INSERT/UPDATE a string field with a datetime in a certain format. But that should be avoided, because it's much easier to work with a datetime than a string.
If you want to change that format for the user use this:
set dateformat dmy;
By running this statement:
DBCC USEROPTIONS;
you will see your dateformat is ydm so you can alway back it up to that if this is not what you wanted :)
You cannot set the output format of a datetime in the datetime itselfs.
If you need to output the datetime as formatted char/varchar, you need to use the convert-function when you select the data:
SELECT CONVERT(char(10), CURRENT_TIMESTAMP, 101) -- format: MM/dd/yyyy
SELECT CONVERT(char(10), CURRENT_TIMESTAMP, 103) -- format: dd/MM/yyyy
In your case:
SELECT #DateMin AS a, CONVERT(char(10), #DateMin, 103) AS b
That works as expected.
If you want to have a mutable data-type, you need to declare it as sql_variant:
DROP TABLE IF EXISTS #t;
CREATE TABLE #t(DateMin sql_variant);
INSERT INTO #t VALUES ('2019-01-13T00:00:00')
UPDATE #t SET DateMin = FORMAT(CAST(DateMin AS datetime), 'dd''/''MM''/''yyyy');
SELECT * FROM #t;
Also, your format-expression needs to explicitly put the / into quotation marks, aka 'dd''/''MM''/''yyyy', otherwise sql-server replaces it with the date-separator specific to the current culture, which would be . in my case.
Just use convert with option 103 instead, it works on all versions of sql-server and it's probably faster.
Also, your insert-statement fails on some versions of sql-server, because iso-date-format is 2019-01-13T00:00:00 and not 2019-13-01 00:00:00
Correct is:
INSERT INTO #t VALUES ('2019-01-13T00:00:00')
Also
DROP TABLE IF EXISTS #t;
is sql-server 2016+ only, otherwise you need
IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
And post sql-server 2005, you should use datetime2 instead of datetime.
You shouldn't use datetime anymore, because datetime uses float, and as such is imprecise - if you insert an iso datetime value, it can do funny things because of the float-point-machine-epsilon, e.g. set it to the next day if you have 23:59:59.999, just as a scary example.
I advise you to never use the sql_variant type. If you have a temp-table with defined columns, just create another column where you will write the char/varchar value to.

How to convert or cast int to string in SQL Server

Looking at a column that holds last 4 of someone's SSN and the column was originally created as an int datatype. Now SSN that begin with 0 get registered as 0 on the database.
How can I convert the column and it's information from an int into a string for future proof?
You should convert. CONVERT(VARCHAR(4), your_col)
If you specifically want zero-padded numbers, then the simplest solution is format():
select format(123, '0000')
If you want to fix the table, then do:
alter table t alter column ssn4 char(4); -- there are always four digits
Then update the value to get the leading zeros:
update t
ssn4 = format(convert(int, ssn4), '0000');
Or, if you just want downstream users to have the string, you can use a computed column:
alter table t
add ssn4_str as (format(ssn4, '0000'));
If you want to add leading zeros, use:
SELECT RIGHT('0000'+ISNULL(SSN,''),4)
First thing never store SSN or Zip Code as any numeric type.
Second you should fix the underlying table structure not rely on a conversion...but if you're in a jam this is an example of a case statement that will help you.
IF OBJECT_ID('tempdb..#t') IS NOT NULL
BEGIN
DROP TABLE #t
END
GO
CREATE TABLE #t(
LastFourSSN INT
)
INSERT INTO #t(LastFourSSN)
VALUES('0123'),('1234')
SELECT LastFourSSN --strips leading zero
FROM #t
SELECT -- adds leading zero to anything less than four charaters
CASE
WHEN LEN(LastFourSSN) < 4
THEN '0' + CAST(LastFourSSN AS VARCHAR(3))
ELSE CAST(LastFourSSN AS VARCHAR(4))
END LastFourSSN
FROM #t
If you are looking for converting values in the column for your purpose to use in application, you can use this following-
SELECT CAST(your_column AS VARCHAR(100))
--VARCHAR length based on your data
But if you are looking for change data type of your database column directly, you can try this-
ALTER TABLE TableName
ALTER COLUMN your_column VARCHAR(200) NULL
--NULL or NOT NULL based on the data already stored in database

Convert datetime and divide into 2 column in SQL server

I'm working in a SQL table which contains a column called 'DATETIME' and it contains values like '201701011730'. The first 8 character is the date and last 4 characters is the time. Now I need to create a column called 'TIME' and also a column called 'DATE' to replace 'DATETIME'. The example has shown below:
DATETIME(201701011730)--> DATE(20170101) and TIME(1730)
I'm trying to work with a update statement with CONVERT function but it doesn't worked. Is there any suggestion to work with?
Assuming your combined column is called dattimCol you can do the following:
select convert(date, left(dattimCol,8)) [date],
convert(time, stuff(substring(dattimCol,9,4),3,0,':')) [time]
from yourTable;
It is important to insert the ':' into the time-string before converting it.
As an update statement this transforms to:
update yourTable SET
dateCol=convert(date, left(dattimCol,8)),
timeCol=convert(time, stuff(substring(dattimCol,9,4),3,0,':'));
OK, here are some short explanations, first substring():
substring(dattimCol,9,4)
(I could have used right(dattimCol,4) instead) will get us the 4 last digits of the datetime string representing the time of day ("1730"). I then "stuff" a colon (":") in the middle of that resultant string by using the stuff() function (available since at least SQL-server 2005)
stuff( sourceString, beginInsertionAtPosition, countOfCharsToDelete, insertionString )
Try as follows:
CREATE TABLE DATES(DATETIME VARCHAR(20))
INSERT INTO DATES VALUES('201701011730')
INSERT INTO DATES VALUES('201801011740')
SELECT * FROM DATES
ALTER TABLE DATES ADD [DATE] VARCHAR(8)
ALTER TABLE DATES ADD [TIME] VARCHAR(4)
DECLARE #DATETIME VARCHAR(MAX)
DECLARE C CURSOR FOR
SELECT DATETIME FROM DATES
OPEN C
FETCH NEXT FROM C INTO #DATETIME
WHILE ##FETCH_STATUS=0
BEGIN
UPDATE DATES SET DATE=(SELECT SUBSTRING(DATETIME,0,9) FROM DATES WHERE DATETIME=#DATETIME) WHERE DATETIME=#DATETIME
UPDATE DATES SET TIME=(SELECT SUBSTRING(DATETIME,9,LEN(DATETIME)) FROM DATES WHERE DATETIME=#DATETIME) WHERE DATETIME=#DATETIME
FETCH NEXT FROM C INTO #DATETIME
END
CLOSE C
DEALLOCATE C
SELECT * FROM DATES
I have used the below code for showing the example you can use the below code
Create Table #ABC(T1 NVARCHAR(500),date nvarchar(255),Time nvarchar(255))
Insert Into #ABC(T1) Values ('201701011730')
Update #ABC
SET date=SUBSTRING(T1,0,9), Time=SUBSTRING(T1,9,LEN(t1))
I think you are using string format rather then date and time format for more information you can go to the following links
http://www.w3schools.com/sql/func_convert.asp
https://msdn.microsoft.com/en-us/library/ms187928.aspx
-----Declare #datetime_str variable where set datetime in string format
Declare #datetime_str varchar(20);
set #datetime_str='201701011730';
select SUBSTRING(#datetime_str,0,9) as date, SUBSTRING(#datetime_str,9,12) as time
--------------------or-------------------
select SUBSTRING('201701011730',0,9) as date, SUBSTRING('201701011730',9,12) as time

Converting varchar datatype to datetime datatype using SQL 2012 management studio

I have a column which has ddmmmyyyy:hh:mm:ss.nnnnnn it is stored as varchar(25). I need to save it as datetime in the same column. I have tried using
update tablename
set columnname = (SUBSTRING(columnname,1,2) + '-' + SUBSTRING(columnname,3,3) + '-' +
SUBSTRING(columnname,6,4) + ' ' + SUBSTRING(columnname,11,8));
and then
alter table tablename
alter columnname datetime;
but later it shows up the error
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
How do I change it any other opinion or any modification for the above query. Please help. Thank you.
As per your given string format, you should use datetime2 data type
Your string format is almost correct, only 1 colon is extra after Year.
If you fix that thing, you can directly cast the varchar field into datetime2. For example first you can replace the extra colon with space by running following query,
UPDATE myTable
SET targetColumn = STUFF ( targetColumn , 10, 1, ' ')
-- ddmmmyyyy:hh:mm:ss.nnnnnn
-- \
-- this colon is extra which is at 10th position
After this you can directly ALTER your table and change the data type to datetime2.
Important: data in all the lines must contain valid date
Here is a test which shows how you can convert
CREATE TABLE testTable(testCol varchar(25));
INSERT INTO testTable(testCol)
VALUES('03Jan2014 18:33:39.999999');
ALTER TABLE testTable ALTER COLUMN testCol datetime2;
SELECT *
FROM testTable
DROP TABLE testTable;
It has already been answered here: Is there a way to convert a varchar to DATETIME in SQL SERVER 2008?
He uses: convert(datetime,'24/05/2012 09:56:06',103)
Although you might have to do some substrings to adapt to a format covered by convert: http://www.sql-server-helper.com/tips/date-formats.aspx
Add a new column
alter table t
add n datetime
Update the new column
update t
set n = datetimefromparts(
cast(substring(o,6,4) as int),
case substring(o,3,3)
when 'jan' then 1
...
when 'dec' then 12
end,
cast(substring(o,1,2) as int),
cast(substring(o,11,2) as int),
cast(substring(o,14,2) as int),
cast(substring(o,17,2) as int),
cast(substring(o,20,6) as int)
)
If you need to drop the old column
alter table t
drop column o

Filter dates stored as varchar in SQL Server

I am using SQL Server 2008 R2 on the EC2 instance. I have a database having 4 fields of all varchar(50).
SELECT
*
FROM
xyz
WHERE
DataDate ='20140609'
This query gives no result.
SELECT
*
FROM
xyz
WHERE
DataDate = (Select MAX(DataDate) from xyz)
This query runs perfectly.
Select MAX(DataDate) from xyz
This query results in 20140609.
I cannot understand why this this happening. Can someone please explain this?
As stated in comments it's likely due to leading spaces in the values. If you do the following to remove any spaces from the values it should work:
SELECT *
FROM xyz
WHERE REPLACE(DataDate, ' ', '')='20140609'
Alternately, you could use LTRIM / RTRIM functions to do this.
Sample SQL Fiddle
create table SampleData(myDate varchar(50))
insert into SampleData(myDate) values(' 20140609 ')
insert into SampleData(myDate) values('20140608')
insert into SampleData(myDate) values('20140607')
insert into SampleData(myDate) values('20140606')
Both of these queries work in the fiddle:
SELECT *
FROM SampleData
WHERE REPLACE(myDate, ' ', '')='20140609'
Select MAX(REPLACE(myDate, ' ', '')) from SampleData
Future Advice:
Even so, it's not a good idea to save dates as varchar for numerous reasons so I would suggest changing that if possible.
The below would perform a conversion on your existing data to convert them to valid dates, whilst removing any spaces, assuming your dates are always in the format YYYYMMDD:
SELECT cast(REPLACE(DataDate, ' ', '') as DateTime) FormattedDate
FROM xyz
To implement this, you could create a new DateTime column on the table and insert the correct date values in to there with something like below and then modify your code to use the new column:
First add a new column to the table:
ALTER TABLE xyz
ADD FormattedDate DateTime NULL
Then update the data in the new column so it holds the converted dates:
UPDATE xyz
SET FormattedDate = cast(REPLACE(DataDate, ' ', '') as DateTime)
in sql spaces count as the character. Then use like operator to this query as
SELECT
*
FROM
xyz
WHERE
DataDate like '%20140609%'
Can you modify the query as below and give it a go ?
SELECT
*
FROM
xyz
WHERE
DataDate ='2014-06-09'