SQL: Invalid column name after table updated - sql

If I run the code below it gives invalid column name. It also gives problems later down in my code.
ALTER TABLE #final
ADD DOB2 DATE
UPDATE #final
SET DOB = '1980-01-01' where DOB ='NULL'
UPDATE #final
SET DOB2 = CAST(DOB as date)
Any reason why? I've already tried CTRL + SHIFT + R
Thank you!

T-SQL (which I presume you are using) compiles lines in batches. A batch is determined by GO boundaries. The problem is the code is compiled before the first statement is executed, so DOB2 is not known during the compile phase -- it hasn't been added yet.
You can easily fix this by adding GO:
ALTER TABLE #final ADD DOB2 DATE
GO
UPDATE #final
SET DOB = '1980-01-01'
WHERE DOB = 'NULL'
UPDATE #final
SET DOB2 = CAST(DOB as date);
I'm not sure what DOB = 'NULL' is supposed to be doing. Dates should be stored using the DATE data type. The DATE data type does not store string values, such as 'NULL'. Perhaps you intend WHERE DOB IS NULL.

Related

Converting date format gives "Conversion failed when converting date and/or time from character string"

The date format in the table is YYYYMMDD and I would like to convert it to the following format but it is failing with an error:
2019-07-23 00:00:00.000
Conversion failed when converting date and/or time from character string
Here is the statement I'm using:
convert(varchar(10), convert(datetime, InstallDate0), 23)
The real problem is the choice of your datatype. varchar is the wrong choice. As a result, it seems that you now have some rows where the value of the "date" has been lost, as it can't be converted to a date.
To properly fix this problem, fix your datatype. Firstly I would create a new column to store the bad values:
ALTER TABLE YourTable ADD BadDate varchar(20); --as it's yyyyMMdd you don't need more than 8 characters, but we'll assume you have some really bad values
UPDATE YourTable
SET BadDate = InstallDate0
WHERE TRY_CONVERT(datetime,InstallDate0) IS NULL;
Now that you've done that, time to update the existing column:
UPDATE YourTable
SET InstallDate0 = CONVERT(varchar(8),TRY_CONVERT(datetime, InstallDate),112);
This'll set every value to the yyyyMMdd format where the value can be converted. NOw you can alter your table:
ALTER TABLE YourTable ALTER COLUMN InstallDate0 date; --AS it's yyyyMMdd, it seems silly to actually use datetime
Now you have a proper datetime column.
You'll then need to inspect the values of BadDate and try to correct them (or admit that any information they held has been lost for ever).
If you "must" have another column with the format, then add a further column:
ALTER TABLE YourTable ADD InstallDate0_f AS CONVERT(varchar(23),InstallDate0,121);
You can determine where the problems are using TRY_CONVERT(). The problem would seem to be the conversion to a datetime, so try this:
select InstallDate0
from t
where try_convert(datetime, InstallDate0) is null;

SQL Server Insert Trigger Improvement

NEED:
Get data out of "comments-type" text/memo field and put it into separate fields upon record insert. Following example uses field TimeStamp for simplicity but uses Update AFTER record is inserted (inefficient) instead of when record is inserted. Need to do this without update.
SOLUTION:
Having never used SQL triggers before, after much wailing and gnashing of teeth, finally came up with something this. It works -- but very inefficiently. Is there a better way?
EXAMPLE:
Imagine a table (Castings) with TimeStamp field formatted: ”2017-12-10 18:44:54”. As records are inserted, fields automatically get populated via a trigger using substring on TimeStamp field. In this case YYYY = “2017”, MM = “12”, DD = “10”, HH = “18”, MN = “44”, SS = “54”. Using a trigger called SQLBuddy.
SCHEMA:
ID bigint (Identify Specification YES auto-increment)
TimeStamp char(19)
YYYY char(4)
MM char(2)
DD char(2)
HH char(2)
MN char(2)
SS char(2)
SQL TRIGGER CODE:
USE [SERT]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[SQLBuddy]
ON [dbo].[Castings]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE Castings
SET YYYY = SUBSTRING(TimeStamp,1,4), MM = SUBSTRING(TimeStamp,6,2), DD = SUBSTRING(TimeStamp,9,2), HH = SUBSTRING(TimeStamp,12,2), MN = SUBSTRING(TimeStamp,15,2), SS = SUBSTRING(TimeStamp,18,2);
SELECT TOP 1 ID FROM Castings ORDER BY ID DESC
END
Your best option is to avoid a trigger altogether and use computed columns on your table. Like this:
CREATE TABLE YourTable
(ID bigint IDENTITY (1,1),
YourDateTime DATETIME,
dYear as DATEPART(YEAR, YourDateTime),
dMonth as DATEPART(MONTH, YourDateTime),
dDay as DATEPART(DAY, YourDateTime),
dHour as DATEPART(HOUR, YourDateTime),
dMinute as DATEPART(MINUTE, YourDateTime),
dSecond as DATEPART(SECOND, YourDateTime)
);
Click here for SQL Fiddle Example
Why are you breaking the timestamp into individual components?
Even worse, why are you storing those components as characters?
To illustrate, what is the order of the following month numbers based on your schema?
'1'
'2'
'10'
'11'
And the answer is:
January
October
November
February
Using integers for the separate components will ensure proper sort order, but you'll still run into a lot of fiddly logic.
Assuming you have
YYYY=2017
MM=12
DD=31
What happens if you add one day?
If your timestamp is coming in as a string, convert it to a datetime data type. You will save so many head-aches later on by having useful, valid timestamps. In addition, you'll have no need for the trigger to separate the pieces. Just insert the whole timestamp into a single field.

SQL Server : convert nvarchar year to datetime

I am trying to convert nvarchar(5) year of birth (e.g. 1972) to a datetime (e.g. 1972-06-01) in a SQL Server table.
Something like:
UPDATE TableName
SET DateOfBirth = CONVERT(datetime, YearOfBirth + '/01/01', 103)
This throws an error
Conversion failed when converting date and/or time from character string
How can I solve this?
What you are doing needs two steps: store the value in the column as a date and then change the type.
In your case, a third step is needed, so the column is big enough to store the value string representation of the date value. I think this will work in SQL Server:
ALTER TABLE TableName ALTER COLUMN DateOfBirth NVARCHAR(32);
UPDATE TableName
SET DateOfBirth = YearOfBirth + '-01-01';
ALTER TABLE TableName ALTER COLUMN DateOfBirth Date;
The first ALTER TABLE alters the column to be wide enough for the new month and day. Then the date is constructed in a standard format (okay, leaving out the hyphens would be even more standard). Then the column is transformed to a date.
If you just want something that looks like a date -- and a lot of criticism on Stack Overflow ;) -- you can eliminate the third step.
This is all you need
UPDATE TableName
SET DateOfBirth = YearOfBirth + '-06-01'
Where YearOfBirth = '1972'

How to compare smalldatetime in stored procedure

I'm writing stored procedure to compare dates but it's not working properly. How can I make it so it compares only the dates but not the time? What I'm trying to do is compare the times and if the Id is null than insert a new entry with the same name but new time. I'm keeping multiple entries with same name but different test time.
ALTER PROCEDURE [dbo].[UL_TestData]
(
#Name varchar(30),
#Test_Time smalldatetime,
#ID INT output
)
AS
Declare #UpdateTime smalldatetime
SELECT #ID=ID FROM Info_User WHERE Name=#Name AND UpdateTime= #Test_Time
IF(#ID IS NULL)
BEGIN
INSERT INTO Info_User (Name, UpdateTime) VALUES (#Name, #UpdateTime)
END
there are a lot of solutions to this depending on what type of DBMS, however here is one:
SELECT #ID=ID FROM Info_User WHERE Name=#Name AND floor(cast(#UpdateTime as float))= floor(cast(#Test_Time as float))
this works because smalldatetime's date is stored a whole numbers, where the time is stored as decimals.
I would cast the dates to a plain date which makes this solution independent of implementation details
select #ID=ID
from info_user
where Name = #Name
and cast (UpdateTime as Date) = Cast(#TestTime as Date)
However, I would either add the date part of the UpdateTime as an additional (calculated) column or split the information into a date and a time part. This makes it much easier to query entries by the plain date.
As a rule of thumb: The type of columns (in general: the table layout) greatly depends on the type of query you usually run against your data.
Edit: As attila pointed out, the date datatype only exists in version 2008 and up

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

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