Conversion Failed Varchar to Date with TOP and WHERE - sql-server

I've got a MSSQL 2012 server that holds olders databases (day by day) of my ERP. Simple JOB restores a newest databases from my backup server and removes the oldest one's. It was working fine for few months, but a week ago it started to fail. One of the queries returns: 'Conversion failed when converting date and/or time from character string.'
All database have the same schema for a name 'DATABASE_date' ex.: 'DATABASE_20150224'.
This is the query:
SELECT TOP 1 name
from sys.databases
where name like 'DataBaseName_%'
order by CAST(right(name,8) as DATE)
IF i remove 'TOP 1' it works fine.
SELECT name
from sys.databases
where name like 'DataBaseName_%'
order by CAST(right(name,8) as DATE)
It seems like MSSQL check's all databases on this server (2 new databases of a different app). But why? There's a 'WHERE' cluase and simple select works just fine.

SQL is a declarative language. A database is free to first order the rows and then filter them, or the other way around.
You are relaying on a where clause to filter out rows that would cause an exception in your string manipulation expression. But SQL Server can run the where after the order by.
One approach is bullet-proofing the order by:
order by
case
when name not like 'DataBaseName_%' then name
else CAST(right(name,8) as DATE)
end
Note that even this isn't 100% guaranteed to work. SQL Server could legally evaluate both sides of the case and throw away the second one.

Related

SQL Server Determining Hard Coded Date as Larger When It's Not?

An old employee left a massive query behind that I've been debugging and it appears that the issue has come down to SQL Server itself determining a comparison differently than what I would have expected.
I have a table with a column col1 containing the value 20191215 as a datetime.
The part in question is similar to the following:
select case when col1 > '01/01/2020' then 1 else 0 end
This statement is returning 1, suggesting that '12/15/2019' is larger than '01/01/2020'.
I do not need assistance correcting the query, as I have already made changes to do so other than using the comparison the previous employee was using, I am simply curious as to why SQL Server would evaluate this as I have described.
I understand that this is not the typically way SQL Server would store dates as well, would the issue simply be the formatting of the dates?
Current SQL Server version is: SQL Server 2014 SP3 CU3.
SQL Fiddle link that shows the same results
Please note that the link does not contain an exact replica of my case
Edit: Included additional info relevant to actual query.
It is a string comparison not a date comparison:
select case when '12/15/2019' > '01/01/2020' then 1 else 0 end
vs
select case when CAST('12/15/2019' AS DATE) > CAST('01/01/2020' AS DATE) then 1 else 0 end
db<>fiddle demo
I am simply curious as to why SQL Server would evaluate this as I have described.
'12/15/2019' it is a string literal, SQL Server does not know you want to treat a date unless you explicitly express your intention.
I have a table with a column col1 containing the value 20191216
If you are comparing with a column then the data type of column matters and data type precedence rules

SSRS rdl preview shows date with bad value shows up despite SQL query that should exclude it

SSRS rdl preview shows date with bad value shows up despite SQL query that should exclude it.
The xml for the query in the rdl-file is:
<Query>
<DataSourceName>ourDataSource</DataSourceName>
<CommandText>
use ourDataBase
----------------------------------------
select convert(date, Date1) as ourDate1, count(*) as ourCountForDate
from ourDataBase.dbo.ourTable
where
(
(Date1 between (getDate()-365) and (getDate()+1) )
)
group by convert(date, Date1)
order by convert(date, Date1)
</CommandText>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
</Query>
This query works just fine in the SQL database when using TSQL directly in SSMS.
However, there is a stray value with a strange year in the database (such as 7654), and it shows up in the results for the rdl file in 'preview' but NOT in the SQL-query results in SSMS.
I have tried lots of variants, with greater than or equal to, and so forth, but this stray value always shows up.
I am using SSRS, Visual Studio 2015, with underlying TSQL. The SSRS uses 2016/01/reportdefinition. The SQL server for the project is SQL Server 2008 R2, 2012 or 2014.
Any ideas?
It's better to create a stored procedure in SQL Server and then have the SSRS call that. Can perform better too. This keeps the data control entirely in the SQL Server.
For those not wanting to use stored-procedures (e.g. due to having to migrate them from various database regions), this worked for me:
Deleting the associated ".data" file helped, also, 'clean' and 'rebuild' the project.
One can also try things like make sure the year starts with 2 (or for some is less than 3).
Here is how one checks for starting with 2:
( left(Datepart(yyyy, Date1),1) = '2' )

How do I avoid date type column of MSSQL INTO PIVOTAL HAWQ null at DBMS migration

We are trying to pull data from external source (mssql) to postgres. But when i checked for invoicedate column entries are getting blank at the same time mssql is showing invoicedate values for those entries.
ie
We tried following query on both the DBMS:
When query executed in SQL Server:
select * from tablename where salesorder='168490'
getting 12 rows where invoicedate column is '2015-10-26 00:00:00.000'
But same query is executed on Postgres
select "InvoceDt" from tablename where salesorder='168490'
Getting 12 rows where the column invoicedate is null.
Question is why?
Postgres InvoiceDt column is coming null rather than we can see that SQL Server is showing appropriate data values.
Why is the data different between SQL Server and Postgres for this particular column?
Vicps, you aren't using Postgres and that is why a_horse_with_no_name is having such a hard time trying to understand your question. You are using Pivotal HDB (formally called HAWQ). HAWQ is now associated with the incubator project, "Apache HAWQ" and the commercial version is "Pivotal HDB".
Pivotal HDB is a fork of Pivotal Greenplum database which is a fork of PostgreSQL 8.2. It has many similarities to Postgres but it is most definitely not Postgres.
You are also using Spring-XD to move the data from SQL Server to HDFS which is critical in understanding what the true problem is.
You provided this example:
CREATE TABLE tablename ( "InvoiceDt" timestamp )
LOCATION ('pxf://hostname/path/to/hdfs/?profile=HdfsTextSimple')
FORMAT 'csv' ( delimiter '^' null 'null' quote '~');
Your file only has one column in it? How is this possible? Above, you mention the salesorder column. Secondly, have you tried looking at the file written by Spring-XD?
hdfs dfs -cat hdfs://hostname:8020/path/to/hdfs | grep 168490
I bet you have an extra delimiter, null character, or an escape character in the data which is causing the problem. You also may want to tag your question with spring-xd too.

Oracle/SQL Server Database Link Date Format Issue

I have an Oracle hs database link set up between SQL Server 2012 and Oracle 11g.
When Selecting date columns in Oracle from the SQL Server database the date comes through fine but as soon as it has to pass through any function then the date gets cropped from 10 to 5 characters.
For example:
Select Input_Date from schema.table#Database
would return 2000-08-18
Select Len(Input_Date) from schema.table#Database
would return 5
(Select Input_Date from schema.table#Database1
Union
Select Input_Date from schema.table#Database2)
would return 2000-
I am at a loss at what to do, at first the select statement also returned 2000- but then I changed the NLS_DATE_FORMAT parameter which allows a view of the full date in a select statement but has not fixed any of the other issues.
When I select dump(input_date,1016) from schema.table#Database I get
Typ=1, Len=10, CharacterSet=AL16UTF16.
I would really appreciate some help as there seems to be very little information about this online.
Many thanks.

Execute query once in SQL Server despite being called mutiple times

I have a situation where a query might be called multiple times from multiple users, but I only want it to run once (per week) against the database. The environment is SQL Server Express so scheduling via SQL Server Agent is not an option. It needs to be 2005 compatible. I'd like to make it as lightweight as possible too, so I'm asking for suggestions. Ideally a database wide declared variable - but I don't think that SQL Server supports such a beast? Thanks
Try something like this:
IF NOT EXISTS ( -- Check if you have the current week content
SELECT *
FROM WeeklyTable
WHERE
DATEPART(YEAR, DateCr) = DATEPART(YEAR, GETDATE())
AND
DATEPART(WEEK, DateCr) = DATEPART(WEEK, GETDATE())
)
BEGIN
-- delete old content
DELETE WeeklyTable
-- insert new content
INSERT INTO WeeklyTable (MyID, MyField1, ... , MyFieldN, DateCr)
SELECT
MyID, MyField1, MyField2, GETDATE()
FROM MainTable
END
You can create indexes you need for the WeeklyTable.
One option would be SQL Scheduler as a add-on to SQL Server Express.
The other option would be to create a small command-line utility that does the querying and schedule that using the Windows Scheduler on the machine where SQL Server Express is installed.
With either of the two setups, you could select the values / numbers you need into a result table once a week, and any requests during the week would be satisfied from that one result table. SQL Server doesn't have "server-wide" variables - but you can always define a table for that purpose...

Resources