can't insert mmddyy10. format proc sql - sql

I have a table with column as_of_date that is formatted as MMDDYY10. in SAS 7.1
proc sql;
INSERT INTO mytable (as_of_date)
VALUES (12/31/2016);
run;
and I get the following error:
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant,
a missing value, ), +, ',', -, MISSING, NULL, USER.
ERROR 200-322: The symbol is not recognized and will be ignored.
Note: if I change the value to 12/31/16 it still does not work. If I put quotes around it ('12/31/2016') I get the error:
ERROR: Value 1 of VALUES clause 1 does not match the data type of the corresponding column in the object-item list (in the SELECT
clause).
If I insert it without slashes (12312016) it is inserted without errors as ********

You need to use the DDMMMYYYY format within quotes and the d modifier:
proc sql noprint;
INSERT INTO mytable (as_of_date)
VALUES ("31dec2016"d);
quit;
Another way to look at it is SAS is looking for the numeric value underneath a date format. You can check the actual value and use the following code to get the same result:
data check;
date = "31dec2016"d;
run;
proc sql noprint;
INSERT INTO mytable (as_of_date)
VALUES (20819);
quit;

Related

Why can't I modify column type in Postgres

I am trying to change type of columns from varchar to integer. When I run the following command
alter table audio_session
alter column module_type_cd type INT USING module_type_cd::integer,
alter column sound_type_cd type INT USING sound_type_cd::integer
I got the error:
ERROR: invalid input syntax for integer: "string"
SQL state: 22P02
The error does not make any sense. There is no "string" in the command at all. What did I do wrong?
The columns audio_session.module_type_cd or audio_session.sound_type_cd has at least one non-numeric value among all values of each row. So, it's impossible to convert to a completely numeric data type.
As an example :
create table Table1( col1 varchar(10), col2 varchar(10) );
insert into Table1 values('1','1');
insert into Table1 values('2','2');
insert into Table1 values('3','C3');
select CAST(coalesce(col1, '0') AS integer) as converted from Table1; -- this works
select CAST(coalesce(col2, '0') AS integer) as converted from Table1; -- but, this doesn't
SQL Fiddle Demo
There is no "string" in the command at all.
But must be in the data. The command you're going to use tries to cast all the columns values to integer. Check this:
select *
from audio_session
where module_type_cd = 'string' or sound_type_cd = 'string';

Create table in SAS using DB2 timestamp

We've recently gotten the accelerator (IDAA) working on our DB2, which I mainly access using SAS.
This requires us, due to network issues, to create tables first, before inserting rows.
My problem is creating a table with the correct timestamp format, I can create the table using a select statement, but this is very slow, but here I can see the format in SAS is DATETIME30.6
But if I try something like:
RSUBMIT prod_acc;
Proc delete data=user.table1; run; %PUT &sqlxrc &sqlxmsg;
proc sql inobs=MAX stimer feedback noerrorstop;
connect to db2(ssid=server);
create table user.table1
(
date datetime30.6
,reference char(16)
,transact char(20)
,alias char(60)
,amount decimal(15,2)
,currency char(3)
);
%PUT &sqlxrc &sqlxmsg;
quit;
run;
Which gives the following in the log
(
15 date datetime30.6
-----------
1 22
200
WARNING 1-322: Assuming the symbol DATE was misspelled as datetime30.
ERROR 22-322: Syntax error, expecting one of the following: a quoted string,
an integer constant, ), ',', CHECK, DISTINCT, FORMAT, INFORMAT, LABEL, LEN,
LENGTH, NOT, PRIMARY, REFERENCES, TRANSCODE, UNIQUE, ^, ~.
ERROR 200-322: The symbol is not recognized and will be ignored.
And if I look in DB2, the column has the type timestmp which SAS don't recognize as a type.
(
31 date timestmp
--------
22
76
ERROR 22-322: Syntax error, expecting one of the following: CHAR, CHARACTER, DATE, DEC,
DECIMAL, DOUBLE, FLOAT, INT, INTEGER, NUM, NUMERIC, REAL, SMALLINT, VARCHAR.
ERROR 76-322: Syntax error, statement will be ignored.
Tried googling and found a lot of different versions of answers, but nothing I can see is relevant to this, the closest was something about manually creating the format, but I can't figure out how to do that.
Any ideas?
It is probably more natural in SAS to define a table's structure using a DATA step rather than PROC SQL.
data userdb.table1;
stop;
length date 8 reference $16 transact $20 alias $60 amount 8 currency $3 ;
format date datetime30.6 amount 15.2 ;
run;
If your libref is pointing to a database then you should be able to use DBTYPE= dataset option to tell SAS what data types to use for your fields in the external database. At least it works for Teradata. These dataset options should work inside PROC SQL also.
proc delete data=userdb.table1; run;
data userdb.table1
(dbtype=
( date='timestamp'
reference='varchar(16)'
transact='varchar(20)'
alias='varchar(60)'
amount='decimal(15,2)'
currency='char(3)'
)
);
stop;
length date 8 reference $16 transact $20 alias $60 amount 8 currency $3 ;
format date datetime30.6 amount 15.2 ;
run;
Can't you just:
create table user.table1
(
"date" TIMESTAMP(6)
,reference char(16)
,transact char(20)
,alias char(60)
,amount decimal(15,2)
,currency char(3)
);
? Remember, in DB2, date is a reserved word, and then it's always safe to put that into double quotes. Alternatively, use a non-reserved word for the column name, like dt or so.
These two lines are incongruous:
connect to db2(ssid=server);
create table user.table1
The first creates a connection for a pass-through query, while the latter creates the table using the libname engine. In this case your first statement is irrelevant as it's not used; you should remove it (unless you use it later and just left it in by mistake in your example).
Since you used the libname syntax, you must follow SAS syntax rather than DB2. There is no specification for datetime type in the create table statement, specifically under the column-definition documentation page. Instead you have this list to choose from:
CHARACTER | VARCHAR <(width)> indicates a character column with a column width of width. The default column width is eight characters.
INTEGER | SMALLINT indicates an integer column.
DECIMAL | NUMERIC | FLOAT <(width<, ndec>)> indicates a floating-point column with a column width of width and ndec decimal
places.
REAL | DOUBLE PRECISION indicates a floating-point column.
DATE indicates a date column.
The way I find best to specify datetime (meaning, most likely to work as you expect) is not to use date but numeric, and then use the format argument to define it as datetime.
proc sql;
create table table1
( date num format=datetime30.6
,reference char(16)
,transact char(20)
,alias char(60)
,amount decimal(15,2)
,currency char(3)
);
quit;
However, I would suggest your best choice is to use passthrough to create the table, so you can use DB2 syntax - since you're creating a table there, not in SAS itself.

SELECT INTO INTEGER ARRAY

I want to assign values in a table column (column type is integer) to integer array. Unfortunately I could not.
--TYPE--
CREATE OR REPLACE TYPE ABILITY_ID_ARRAY IS VARRAY(100) OF INTEGER
--DECLARE IN PROCEDURE
ABILITY_IDS ABILITY_ID_ARRAY;
--STATEMENT--
SELECT ABILITY_FK INTO ABILITY_IDS
FROM T_EDUCATION_ABILITY_REL
WHERE EDUCATION_FK = edu_id;
I received this error:
[Error] ORA-00932 (16: 12): PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
You need to use BULK COLLECT clause to store a resultset into a collection variable.
Please study the documentation of SELECT INTO statement:
https://docs.oracle.com/database/121/LNPLS/selectinto_statement.htm#LNPLS01345
into_clause
With this clause, the SELECT INTO statement retrieves one or more columns from a single row and stores them in either one or
more scalar variables or one record variable.
bulk_collect_into_clause With this clause, the SELECT INTO statement retrieves an entire result set and stores it in one or more
collection variables.
The PL/SQL statament should look like this in your case:
SELECT ABILITY_FK BULK COLLECT INTO ABILITY_IDS
FROM T_EDUCATION_ABILITY_REL
WHERE EDUCATION_FK = edu_id;

Converting text field to date in SAS SQL

I am trying to convert a text field from a SAS table with the form '2014-12-31' into a another SAS table as a date field. The below does not work:
proc sql outobs=50;
create table Dbtr_Clnt_Generl_Inf as
select FACS_Schema_ID '',
'DBACCT*'n as ACCOUNT_NUM '',
DBLSTDTI as Date_Listed format=date09.
from sqlsrv10.Acct_Dbtr_Clnt_Generl_Inf;
quit;
I get the following error:
ERROR: Character expression requires a character format.
You use INPUT to convert types in SAS.
proc sql outobs=50;
create table Dbtr_Clnt_Generl_Inf as
select FACS_Schema_ID '',
'DBACCT*'n as ACCOUNT_NUM '',
input(DBLSTDTI,yymmdd10.) as Date_Listed format=date09.
from sqlsrv10.Acct_Dbtr_Clnt_Generl_Inf;
quit;
That is most likely the correct informat based on your question.

How to insert french number format in oracle SQL table

I am facing the issue to insert the french number in a number field of oracle.I am using SQL Developer IDE. When i insert the number(say 3,4) its says invalid number. Specifically,
I don't want to replace the value 3,4 to 3.4.
I tried with changing the NLS Setting also (using command
Alter session set NLS_NUMERIC_CHARACTERS=',';
If I use this command I am able to insert directly in editor but insert command is not working due to comma, Oracle assume that its another value.
Any help would be appreciated.
You can't and you don't need to.
The number format for SQL literals requires the . for the decimal separator.
In the column itself the decimal separator isn't stored at all. You just need to change the display format of the number. This is ideally done in your application, not on SQL level. But if you require this in the SQL output, use to_char() to format your numbers:
select to_char(your_number_column, '9999D99')
from your_table;
The D in the format mask will be replaced with the decimal separator defined by the current session's NLS settings.
A dot . and , are returned literally:
select to_char(your_number_column, '9999,99')
from your_table;
More details on the to_char() format mask can be found in the manual: https://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements004.htm#BABIGFBA
You application/ide may be performing an implicit conversion of character data into number, which uses the session default nls_numeric_characters.
You can force the insert command to perform an explicit conversion as follows using to_number:
SQL> alter session set nls_language = ENGLISH;
Session altered
SQL> alter session set nls_numeric_characters = ',.';
Session altered
SQL> create table t1 (num_col number);
Table created
SQL> insert into t1 (num_col) values ('3.4');
insert into t1 (num_col) values ('3.4')
ORA-01722: invalid number
SQL> -- this is equivalent to:
SQL> insert into t1 (num_col) values (to_number('12345,678', '999999D999', 'NLS_NUMERIC_CHARACTERS=.,'));
insert into t1 (num_col) values (to_number('12345,678', '999999D999', 'NLS_NUMERIC_CHARACTERS=.,'))
ORA-01722: invalid number
SQL> -- now converting explictly
SQL> insert into t1 (num_col) values (to_number('12.345,678', '999999D999', 'NLS_NUMERIC_CHARACTERS=,.'));
1 row inserted
SQL> insert into t1 (num_col) values (to_number('12345,678', '999999D999', 'NLS_NUMERIC_CHARACTERS=,.'));
1 row inserted
in NLS_NUMERIC_CHARACTERS the first character is the decimal separator and the second one is the thousands grouping marker.
The docs have more info:
https://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_functions_2117.htm