Standard SQL Date vs Legacy SQL Date - google-bigquery

I noticed that there is an inconsistent result from Date Function in Standard SQL and Legacy SQL,
In standard SQL, current_date() returns a DATE data type, however, in Legacy SQL, current_date() returns a String data type.
Then, If I create a table which has 'Date' column by using Standard SQL, later on, when I querying the table using Legacy SQL, I have to format 'Date' from Date Data Type To String Data Type, or the other way around.
Unlike Timestamp Data Type, I can query the same table across different SQL Language. Is there an easy way to query in Standard SQL and legacy SQL without converting between Data type and String type?
Thank you in advance.

Legacy SQL has very limited support for the civil time types, so you're better off sticking with standard SQL if possible.

Related

What is standard date time string format for SQL query for insering data in datetime columns?

Today I faced a problem while porting an SQL server database to H2DB. The SQL queries I had written to insert date time, wasn't working on H2DB. i.e '26-Jun-2019 01:00:00' gave exception on H2DB. My question is what is standard format for inserting date time which is database independent?
The standard format as defined by the SQL standard is the ISO format, prefixed with the keyword DATE, e.g.
DATE '2019-06-26'
or for a timestamp:
TIMESTAMP '2019-06-26 17:42:00'
However not all database products support the SQL standard in that regard, so you will most probably not find one single format that will work across all database products.

SAS - SQL ODBC connection - converts date type to text [duplicate]

I'm fairly new to SAS and recently we migrated some of our SAS datasets to a SQL Server table but we are still using SAS to do our analysis. I have run into a problem when SAS is trying to bring in the data from the SQL Server table and have SAS check if the srv_edt date is between the SAS dates of dos_beg_dt1 and dos_end_dt1.
When SAS tries to compare the dates I get an error of: ERROR: WHERE clause operator requires compatible variables.
The dos_beg_dt1, dos_end_dt1, and srv_edt (SQL date format) all "appear" in the format of yyyy-mm-dd. When I bring the srv_edt into a SAS table it reads it as a character date. So I've tried changing the format of the dates and then I will get an error like:ERROR: Variable srv_edt has been defined as both character and numeric. I can't seem to find the correct format or function to get SAS to do the comparison to see if the srv_edt (SQL) is between the dos_beg_dt1 and dos_end_dt1 SAS dates.
The code I use is as follows:
libname sql odbc dsn=test schema=dbo;
%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning),yymmdd10.);
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end),yymmdd10.);
data sample;
set sql.table;
where &dos_beg_dt1 <= srv_edt <= &dos_end_dt1;
run;
For reference I am using SAS 9.2 to connect via odbc to SQL Server 2008.
Any help or advice would be greatly appreciated.
SAS stores and uses dats as numeric variables. If you had not identified the column srv_edt as a date column when you migrated the database to SQL server everything would now process correctly.
I assume that currently and into the future you will just store the tables in SQL server and all the processing will be in SAS.
You have a few options.
1/ re-migrate the SAS tables but identify all the date, time and datetime columns as just numeric. They all can be stored as 8 byte floating point. The date variables may also be stored (in SQL Server) is long integers. The code would need a slight change so that the macro variables would be numeric.
%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning));
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end));
2/ keep the date, time, and datetime variables in SQL Server format and change the data type of the column when using the data. (Note the reverse will be necessary on output). SQL Server will present the date variables as strings (character) so that your expression above will need to be -
%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning));
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end));
data sample;
set sql.table;
where &dos_beg_dt1 <= (input(srv_edt, yymmdd10.0)) <= &dos_end_dt1;
That to make sure when using SAS processing the type is numeric which is what the input function will do.
3/ keep the date, time, and datetime variables in SQL Server format and change your working to accommodate that fact. That is comparisions will be using character data and output will need to produce characters. SQL Server will present the date variables as strings (character) so that your expression above will need to be -
%let dos_beg_dt1 = %sysfunc(intnx(qtr,&date,-1,beginning), yymmdd10.);
%let dos_end_dt1 = %sysfunc(intnx(qtr,&date,-1,end), yymmdd10.);
data sample;
set sql.table;
where ("&dos_beg_dt1" <= srv_edt) and
(srv_edt <= "&dos_end_dt1");`
Note double quotes " " required surrounding macro variables as this
comparison is numeric.
If the column srv_edt is showing up in your SAS data set as a character variable, that means it is really a character variable or it's been converted to character by the ODBC driver you are using (possibly because the native data type is not supported by ODBC).
You'd be better off changing this to a PROC SQL pass-thru query if possible. You would need to figure out the native syntax that corresponds to the SAS intnx function (and I cannot help you there). As written, the entire table must be read (because you are using a SAS function). If you use a pass-thru query, SAS will only receive the rows that match the whee clause.
There might be setting in the ODBC driver that control this behavior. I'll add the ODBC and SQL Server tags to your question; you may get more "hits".
SQL Server introduced new date and datetime types in SQL Server 2008 (prior, there was only one type for all date/datetime variables). This usage note suggests that you need to install a new set of SQL Server ODBC drivers for SAS to read the date variables correctly. It suggests this would be installed normally if you have SQL Server 2008 Tools (like SQL Server Management Studio) on the machine that is doing the ODBC connection, but you might have multiple drivers installed and need to ensure you are using the right one.
That said, it is not a bad idea to use pass-through SQL to pull the data across, as that might make it easier to do the pull (as you don't have to worry as much about the ODBC driver). The generalized pass through connection string is
proc sql;
connect to odbc (required="driver=sql server native client 10.0;
Server=server;Trusted_Connection=Yes;DATABASE=database;");
create table X as select * from connection to odbc(... sql server native code here ...);
quit;
From your question it sounds like you're more of a SQL person and can then construct the query yourself; if you are not, either edit the question to include that request (and then either a SQL Server person or myself will answer). You can use SAS macro variables in that query (ie, to pass the current date) as long as you do not enclose them or the query in single quotes.

SQL: to_char alternative for Oracle AND SQL-Server

I have some sql statements, which i am using for Oracle. This sql statements are used by a programm from me.
I want to support Oracle and SQL-Server with my program without having different sql statements for Oracle and SQL-Server.
Which alternative can i use for the specific Oracle SQL-Statements:
to_char(FIELDNAME, 'YYYY')
to_char(FIELDNAME, 'YYYYMMDD')
to_char(FIELDNAME, 'DD.MM.YYYY')
The sql statements have to work for Oracle and SQL-Server.
Even if at a first glance the SQL implementation from two different vendors looks similar, when working with real life enterprise applications you will stumble upon a large number of differences, and I am only talking about SQL, when comparing PL/SQL with T-SQL there is hardly any resemblance left.
When trying to reduce the usage of two databases to only common functionality, you will loose a lot of their power, you could as well use a txt file on the file system.
One elegant solution, as someone already suggested, would be to leave the columns in the database as DATE data type and extract your data in the application code that stands above the database, if any. For example, in Java, you will map your database DATE columns to java.sql.Date no matter if that date comes from Oracle or from SQL Server.
Still, if you want to get your formatted data from the database, you could create separate columns that hold the formatted date, for example :
FIELDNAME | FIELDNAME_YYYY | FIELDNAME_YYYYMMDD | FIELDNAME_DDMMYYYY
I don't think there are common functions to do what you want. Oracle supports the ANSI standard extract() function for extracting date parts. SQL Server has separate functions for YEAR(), MONTH(), and DAY(). Oracle uses TO_CHAR(); SQL Server uses CONVERT().
One option is to define the functions YEAR(), MONTH(), and DAY() in Oracle and then use string concatenation (via the CONCAT()) function to combine the data. Or, write specific functions in each database for what you want to do. Or, perhaps, someone has implemented TO_CHAR() in SQL Server and you can grab the code from the web.
Finally i found a solution. Maybe its useful some other people too.
You can set the input format for a date...
Oracle: ALTER SESSION SET NLS_DATE_FORMAT = 'DD.MM.YYYY'
SQL-Server: SET DATEFORMAT dmy

Creating a custom data type with specific format

I'm moving from an access database to a SQL Server database and wanted to know if I can create my own data type for dates.
I want to have my custom date type to have a format of mm/dd/yyyy instead of yyyy/mm/dd. Is this possible to do?
Use the default/built-in data type to store a specific data type. This will be more efficient and reliable as sql server will only allow the valid data to be stored (data integrity).
Also this will allow you to make use of all the built-in functions to work with that specific data type. In your case if you use Sql Server's datetime data type you will be able to make use of all the datetime functions (DATEDIFF() , DATEADD() , DAY() , YEAR() , MONTH(), DATENAME() etc).
As far as how you see the date/datetime values stored in your database, again you will always have built-in datatime functions to format the date values as it suits you.
Once you have stored the date/datetime values in sql server database and you want to view date value as mm/dd/yyyy instead of yyyy/mm/dd simply do the following:
SELECT CONVERT(VARCHAR(10), [DateColumn], 101)
Custom datatypes are there to be used but there are some very odd issues with them, avoid them whenever you can :)

How can I convert a SQL Server date format to Oracle?

I am working on migration of data from an old system to a new system. As part of migration, the data from the legacy system, (stored in files) is pumped into MS SQL Server. Now my app runs on Oracle. I'm having a problem with the date/timestamp.
The timestamp format in MS SQL Server data is:
2008.12.23 00:00:00
Oracle expects:
23/12/2008 00:00:00
or
23-DEC-2008 00:00:00
What would be the best way to import the data? Oracle's to_date() function didn't work as I thought it would.
I assume you're using insert statements?
Convert your dates using:
TO\_DATE(sql\_server\_value,'YYYY.MM.DD HH24:MI:SS')
You can put a second parameter on the to_date function to specify in what format the incoming data is. You will likely have to make SQL server pump the data out as a string.
http://www.techonthenet.com/oracle/functions/to_date.php
Use CONVERT to convert your internal datetime columns to text in whatever format you wish on the SQL Server side.