I have a silly question...
for some reason I just can't get it work...
I want to insert a row into an empty table using the today(function).
This is what I do:
insert into gal_risk_factor (RISK_FACTOR_ID, VALID_FROM_DTTM,
RISK_FACTOR_NM, EFFECTIVE_FROM_DTTM, EFFECTIVE_TO_DTTM)
values ("1",today(),
"GGG",
"01JAN1901:00:00:00"dt, "01JAN2999:00:00:00"dt
)
This is the error I get:
today(),
_____
22
202
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 202-322: The option or parameter is not recognized and will be ignored.
What am I missing here...?
Thank you in advance,
Gal.
I guess the VALUES list cannot contain function, only constants.
Try creating a macro var and use it:
%let today=%sysfunc(today());
insert into gal_risk_factor (RISK_FACTOR_ID, VALID_FROM_DTTM,
RISK_FACTOR_NM, EFFECTIVE_FROM_DTTM, EFFECTIVE_TO_DTTM)
values ("1", &today,
"GGG",
"01JAN1901:00:00:00"dt, "01JAN2999:00:00:00"dt
)
Edit:
In case VALID_FROM_DTTM is meant to store datetime values use a constant like this:
%let today_dttm=%sysfunc(dhms(%sysfunc(today()), 0, 0, 0));
Related
I am trying to set missing values to NULL in SAS dataset for a numerical variable,
how can I do this?
as missing is null in sas?
If you're asking how to have the period not display for a missing value, you can use:
options missing=' ';
That however doesn't actually change them to null, but rather to space. SAS must have some character to display for missing, it won't allow no character. You could also pick another character, like:
options missing=%sysfunc(byte(255));
or even
options missing="%sysfunc(byte(0))";
I don't recommend the latter, because it causes some problems when SAS tries to display it.
You can then trim out the space (using trimn() which allows zero length strings) if you are concatenating it somewhere.
Taking the question very literally, and assuming that you want to display the string NULL for any missing values - one approach is to define a custom format and use that:
proc format;
value nnull
.a-.z = 'NULL'
. = 'NULL'
._ = 'NULL'
;
run;
data _null_;
do i = .a,., ._, 1,1.11;
put i nnull.;
end;
run;
You can set values to missing within a data step, when it is numeric :
age=.;
to check for missing numeric values use :
if numvar=. then do;
or use MISSING function :
if missing(var) then do;
IS NULL and IS MISSING are used in the WHERE clause.
Look at : http://www.sascommunity.org/wiki/Tips:Use_IS_MISSING_and_IS_NULL_with_Numeric_or_Character_Variables
I want to compare 2 date/timestamp fields. One of those comes from a table on Oracle, second one comes from a mapping variable for which a value is define in a parameter file. The datatype of the variable is defined as date/timestamp in the mapping. A filter makes the comparison for which the condition is:
DATE_COMPARE(LAST_UPD, $$CDC_STRT_TS) >=0 AND DATE_COMPARE(LAST_UPD, $$CDC_END_TS) < 0
However, on executing the session, I receive:
TE_7002 [<<PM Parse Error>> missing operator
... DATE_COMPARE(LAST_UPD, 02/01/2014>>>> <<<<01:01:01.000000000) >=0 AND DATE_COMPARE(LAST_UPD, 03/01/2014 01:01:01.000000000) < 0]
It appears that Informatica is putting a space when replacing the variable with its value. If I convert it to a string and use date conversion functions then Informatica encloses the variable in single quotes and does not replace it with the value defined in the parameter file (notice the where clause).
ORA-00942: table or view does not exist
Oracle Fatal Error
Database driver error...
Function Name : Execute
SQL Stmt : SELECT CX_NET_TER_HIER.ROW_ID, CX_NET_TER_HIER.CREATED, CX_NET_TER_HIER.CREATED_BY, CX_NET_TER_HIER.LAST_UPD, CX_NET_TER_HIER.LAST_UPD_BY, CX_NET_TER_HIER.MODIFICATION_NUM, CX_NET_TER_HIER.CONFLICT_ID, CX_NET_TER_HIER.PAR_ROW_ID, CX_NET_TER_HIER.DB_LAST_UPD, CX_NET_TER_HIER.AREA_CODE, CX_NET_TER_HIER.AREA_CODE_NAME, CX_NET_TER_HIER.BILL_INTG_ID, CX_NET_TER_HIER.CITY, CX_NET_TER_HIER.DB_LAST_UPD_SRC, CX_NET_TER_HIER.NAME, CX_NET_TER_HIER.PRODUCT_ALIAS, CX_NET_TER_HIER.REFRENCE_ID, CX_NET_TER_HIER.TERRITORY_ID, CX_NET_TER_HIER.TERRITORY_TYPE, '12775'
FROM CX_NET_TER_HIER
WHERE
(((CASE WHEN CX_NET_TER_HIER.LAST_UPD = TO_TIMESTAMP('$$CDC_STRT_TS', 'MM/DD/YYYY HH24:MI:SS') THEN 0 WHEN CX_NET_TER_HIER.LAST_UPD > TO_TIMESTAMP('$$CDC_STRT_TS', 'MM/DD/YYYY HH24:MI:SS') THEN 1 WHEN CX_NET_TER_HIER.LAST_UPD < TO_TIMESTAMP('$$CDC_STRT_TS', 'MM/DD/YYYY HH24:MI:SS') THEN -1 ELSE NULL END) >= 0) AND ((CASE WHEN CX_NET_TER_HIER.LAST_UPD = TO_TIMESTAMP('$$CDC_END_TS', 'MM/DD/YYYY HH24:MI:SS') THEN 0 WHEN CX_NET_TER_HIER.LAST_UPD > TO_TIMESTAMP('$$CDC_END_TS', 'MM/DD/YYYY HH24:MI:SS') THEN 1 WHEN CX_NET_TER_HIER.LAST_UPD < TO_TIMESTAMP('$$CDC_END_TS', 'MM/DD/YYYY HH24:MI:SS') THEN -1 ELSE NULL END) < 0))
Oracle Fatal Error].
The parameter file looks like:
[s_CRM_10_020_LoadToStageTableCXNETTERHIER]
$$CDC_LAST_TS=01/01/2014 01:01:01
$$CDC_STRT_TS=02/01/2014 01:01:01
$$CDC_END_TS=03/01/2014 01:01:01
I have tried using 03/01/2014_01:01:01 in parameter file to avoid the space and set the session DateTime Format String to handle the underscore, but this does not help.
I think if there is some way to avoid the enclosing into single quotes in case of string or avoiding the space error in case of date/timestamp then the session will run fine.
Any help is really appreciated. Thank you!
You probably declared the variable as a Expression Variable (IsExprVar = True). So, it first expands the variable, and then evaluates the expression in filter causing the error due to the space.
The same reason, why the variable is not expanded in SQ.
Try making IsExprVar=False. Or, you can define the variable as string, and convert it to date in the expression.
I have a test table using a Microsoft SQL Server that is defined like this:
CREATE TABLE [dbo].[Table] (
[FirstName] NVARCHAR (255) NULL,
[LastName] NVARCHAR (255) NULL
);
There's just one row in the table with the values "person" and "man", respectively.
I'm trying to add a function that will update the values of that row but I keep running into this "[Microsoft][ODBC SQL Server Driver]String data, right truncation State code: 22001" error and I cannot figure out what the problem is. I've looked around and people say that it is caused by the data being too long to fit in the column but that's impossible because the string I'm trying to update with is only two characters, and as you can see in the table definition there is plenty of space for it.
I'm using a prepared statement for optimization purposes and the code creating it looks something like this:
const tString query("UPDATE \"" + tableName + "\" SET " + setClause + " WHERE " + whereClause + ";");
SQLHSTMT statement;
SQLAllocHandle(SQL_HANDLE_STMT, fSQLConnection, &statement);
SQLPrepareW(statement, (SQLWCHAR *) query.mWideStr(), SQL_NTS);`
The query string looks like this:
UPDATE "Table" SET "FirstName" = ?, "LastName" = ? WHERE "FirstName" = ? AND "LastName" = ?;
And then I am binding the parameters like this:
// We have our own string class that we use, which is where the mWideStr() and mGetStrSize()
// come from. mWideStr() returns a pointer to a UCS-2 buffer and mGetStrSize() returns the
// size in bytes.
SQLLEN pcbValue(SQL_NTS);
SQLUSMALLINT paramIndex(1);
// Call this for each parameter in the correct order they need to be bound, incrementing the
// index each time.
SQLBindParameter(statement, paramIndex++, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_VARCHAR, 255, 0, (SQLPOINTER) paramValue.mWideStr(), paramValue.mGetStrSize(), &pcbValue);
The first and second bound parameters are the new values which are both just "55", then third would be "person" and fourth would be "man".
Then to execute the statements it's just a call to SQLExecute():
SQLExecute(statement);
The call to SQLExecute() fails and then the error is generated and there is some more code that outputs the error message. As far as I can tell this should all be working perfectly fine. I have another database using Oracle that uses the exact same setup and code and it works without any issues, it's just SQL Server that's barfing for some reason. Is there something obviously wrong here that I'm missing? Does SQL Server have some weird rules that I need to add somewhere?
The SQLLEN pcbValue(SQL_NTS); variable being passed to SQLBindParameter() was going out of scope between binding the parameters and executing the statement, which means that some garbage data was being pointed to in the parameter binding. I also realized that you don't need to specify the last parameter. You can just pass NULL and it will act as if it is a nul-terminated string.
So the fix was to remove the SQLLEN pcbValue(SQL_NTS); variable and to just pass NULL to SQLBindParameter() for the last parameter instead.
Stupid mistake, but worth noting I suppose.
I have text provided as varchar2 variable, for exameple:
EXER/ATP-45/-//
MSGID/BIOCHEM3/-/-/-/-/-//
GEODATUM/UTM//
PAPAA/1KM/-//15KM/-//
So, every line separator is // (but there can be also spaces, new lines etc and they should be ignored). '-' is indicating blank field and should be ignored. I have also defined new object type, defined as follows:
TYPE t_promien IS RECORD(
EXER VARCHAR2,
MSGID VARCHAR2(1000),
PAPAA t_papaa
......
)
I need to extract data from corresponding rows into new variable that has t_promien type and set its field, for example - EXER should has 'ATP-45' value, MSGID should has 'BIOCHEM3', PAPAA should has ('1KM','15KM') value (t_papaa is my custom type too and it contains 2 varchar fields).
What is the best way to do this inside oracle PL-SQL procedure? I need to extract needed data into out parameter. Can I use regex for this (how?) Ufortunatelly, I'm totally newbie with oracle, so...
Can you give me some tips? Thanks.
You can do this with REGEXP_SUBSTR using something like this:
SELECT REGEXP_SUBSTR('EXER/ATP-45/-//
MSGID/BIOCHEM3/-/-/-/-/-//
GEODATUM/UTM//
PAPAA/1KM/-//15KM/-//', 'EXER/[^/]+/', 1, 1) AS EXER
FROM DUAL;
The important bit above is 'EXER/[^/]+/' which is looking for a string that starts with the literal EXER/ followed be a sequence of characters which are not / and ended by a final /.
The above query will return EXER/ATP-45/, but you can use standard string functions like SUBSTR, LTRIM or RTRIM to remove the bits you don't need.
A simple demonstration of the use of REGEXP_SUBSTR in PL/SQL.
CREATE OR REPLACE PROCEDURE TEST_REGEXP_PROC(VAR_PI_MSG IN VARCHAR2,
T_PO_PAPAA OUT T_PROMIEN) AS
VAR_L_EXER VARCHAR2(1000);
VAR_L_MSGID VARCHAR2(1000);
BEGIN
SELECT SUBSTR(REPLACE(REGEXP_SUBSTR(VAR_PI_MSG, 'EXER/[^/]+/', 1, 1),'/'),5)
INTO VAR_L_EXER
FROM DUAL;
T_PO_PAPAA.EXER := VAR_L_EXER;
SELECT SUBSTR(REPLACE(REGEXP_SUBSTR(VAR_PI_MSG, 'MSGID/[^/]+/', 1, 1),'/'),6)
INTO VAR_L_MSGID
FROM DUAL;
T_PO_PAPAA.MSGID := VAR_L_MSGID;
END;
Hope this will get you started.
Is there an equivalent of the Oracle NVL function in SAS?
For example, if I have a where clause in SAS that says:
where myVar > -2;
it is not going to include any rows that have myVar = .
If I want to treat missing values as zero, i have to say:
where myVar > -2 or missing( myVar )
I'd like to be able to do something like:
where NVL( myVar, 0 ) > -2 // or some SAS equivalent
Is there something like this in SAS?
The coalesce function should do the job.
where coalesce(myVar,0) > -2
I'm not sure if the function became available in SAS 9, so if you have a really old SAS version this might not work.
Using the coalesce function is the right way to do this.
But if you have an old version of SAS where coalesce isn't implemented, you can use this trick:
where sum(myVar,0) > -2
If you use the sum function in SAS for adding, any non-missing number in the summation will force the result to be non-missing.
Thus adding 0 with the sum function will transform a missing value to 0, and non-missing values will remain unaltered.
One thing that y can do is
like
array varlistname var1 var2 var3 varn;
if array <>. then output;
It will ouput data sets having non missing values