Following is a Teradata case statement that converts false, False, F, f to 0 and true, True, T, t to 1 else my_col_ value, I would like to do the same using Snowflake file format.
CASE WHEN my_col ='\N' THEN NULL
WHEN my_col = 'false' OR my_col = 'False' OR my_col = 'F' OR my_col = 'f' THEN '0'
WHEN my_col = 'true' OR my_col = 'True' OR my_col = 'T' OR my_col = 't' THEN '1'
ELSE my_col END as "my_col_"
if its case statement, it could be simplified as :
CASE WHEN my_col ='\N' THEN NULL
WHEN my_col IN ('false','False','F','f') THEN '0'
WHEN my_col in('true' ,'True','T','t') THEN '1'
ELSE my_col END as "my_col_"
Hoping by "Snowflake file format" mean you just need equivalent Snowflake query for above tearadata code and you really don't mean those 6 different file format that Snowflake supports. in That case.:
Considering my_col contains string data , same teradata code should work fine . Little compact version of above code can be as below
CASE WHEN my_col ='\N' THEN NULL
WHEN my_col IN ('false','False','F' ,'f') THEN '0'
WHEN my_col IN ('true' , 'True' ,'T' ,'t') THEN '1'
ELSE my_col END as "my_col_"
I would actually modify your statement to something like this if possible:
CASE WHEN TRY_TO_BOOLEAN(my_col) = True THEN '1'
WHEN TRY_TO_BOOLEAN(my_col) = False THEN '0'
ELSE NULL END
If your target table is already a BOOLEAN field, then this will do it as well without the need for a CASE statement:
TRY_TO_BOOLEAN(my_col)
And as Simeon said in the comments, this can be done directly in the COPY INTO statement, if necessary, but has nothing to do with a FILE FORMAT. Also, I would recommend you load the data raw, and then transform the data inside of Snowflake, instead. It will perform better that way.
Related
Using ROracle package in R Studio 2021.09.0
I have a stored procedure
PROCEDURE A_TEST_RORACLE_IN_BOOLEAN_OUT_CLOB (v_bool IN BOOLEAN, v_resp OUT CLOB) IS
BEGIN
IF (v_bool=TRUE) THEN
v_resp := 'The value passed is TRUE';
ELSIF (v_bool=FALSE) THEN
v_resp := 'The value passed is FALSE';
ELSE
v_resp := 'The value passed is NULL';
END IF;
END A_TEST_RORACLE_IN_BOOLEAN_OUT_CLOB;
I have a functioning driver/con etc - have called similar test procedures using INTEGER IN and CLOB OUT vars ... hung up on the BOOLEAN thing.
I call it using these lines in an R script.
v_answer = FALSE
df_test <- data.frame(v_bool=v_answer,v_resp=as.character(NA),stringsAsFactors=FALSE)
attr(df_test$v_bool, "ora.parameter_name") <- "oompalumpa"
attr(df_test$v_bool, "ora.parameter_mode") <- "IN"
attr(df_test$v_bool, "ora.type") <- "BOOLEAN"
attr(df_test$v_resp, "ora.parameter_name") <- "jazzy"
attr(df_test$v_resp, "ora.parameter_mode") <- "OUT"
attr(df_test$v_resp, "ora.type") <- "CLOB"
v_test_smpl_mv <- 'BEGIN TESTSCHEMA.TESTPACKAGE.A_TEST_RORACLE_IN_BOOLEAN_OUT_CLOB(:oompalumpa,:jazzy);END;'
v_result <- oracleProc(con,v_test_smpl_mv,df_test)
get response
Error in .oci.oracleProc(conn, statement, data = data, prefetch = prefetch, :
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'A_TEST_RORACLE_IN_BOOLEAN_OUT_CLOB'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
have tried:
df_test <- data.frame(v_bool=as.logical(v_answer),v_resp=as.character(NA),stringsAsFactors=FALSE)
and
leaving out the BOOLEAN specific ora.type attr()
and setting the ora.type attr() to other types (CHAR,VARCHAR,RAW)
and changing the value of v_answer
v_answer = 'FALSE'
... all roads lead to silence or ORA- errors.
this ad-hoc pl/sql call returns 'The value passed is NULL' as expected.
DECLARE
v_clob CLOB;
v_char boolean;
BEGIN WRM_ADMIN.WRM_MAINT_DATA_LOAD_02.A_TEST_RORACLE_IN_BOOLEAN_OUT_CLOB(v_char,v_clob);
DBMS_OUTPUT.PUT_LINE(v_clob);
END;
Left to conclude that BOOLEAN parameters are a bad idea, or at the very least unsupported in OCI/RORACLE ... but I cannot figure out where that is documented.
I have looked here:
https://cran.r-project.org/web/packages/ROracle/ROracle.pdf
And googled the google ... nothing comes back that helps me.
Thanks in advance for any definitive guidance you can offer.
Contacted the maintainer of the package # Oracle and got a report back that they will add BOOLEAN support to a future release of ROracle; they were extremely responsive and helpful.
In the meantime ... presuming you already have other code that uses BOOLEAN values and you need a quick workaround.
-- change the in parameters to char
PROCEDURE A_TEST_RORACLE_IN_CHARBOOL_OUT_CLOB (v_bl_flg IN CHAR default 'F', v_resp OUT CLOB) IS
-- ADD THIS vvv
v_bool BOOLEAN;
BEGIN
-- ADD THIS vvv
IF (v_bl_flg = 'T') THEN
v_bool := TRUE;
ELSIF (v_bl_flg = 'F') THEN
v_bool := FALSE
END IF;
-- ADD THIS ^^^^
IF (v_bool=TRUE) THEN
v_resp := 'The value passed is TRUE';
ELSIF (v_bool=FALSE) THEN
v_resp := 'The value passed is FALSE';
ELSE
v_resp := 'The value passed is NULL';
END IF;
END A_TEST_RORACLE_IN_CHARBOOL_OUT_CLOB;
and adjust the R-part accordingly
v_answer = 'F'
df_test <- data.frame(v_bl_flg=as.character(v_answer),v_resp=as.character(NA),stringsAsFactors=FALSE)
## attr(df_test$v_bl_flg, "ora.parameter_name") <- "oompalumpa"
attr(df_test$v_bl_flg, "ora.parameter_mode") <- "IN"
attr(df_test$v_bl_flg, "ora.type") <- "CHAR"
## attr(df_test$v_resp, "ora.parameter_name") <- "jazzy"
attr(df_test$v_resp, "ora.parameter_mode") <- "OUT"
attr(df_test$v_resp, "ora.type") <- "CLOB"
v_test_smpl_mv <- 'BEGIN TESTSCHEMA.TESTPACKAGE.A_TEST_RORACLE_IN_CHARBOOL_OUT_CLOB(:oompalumpa,:jazzy);END;'
v_result <- oracleProc(con,v_test_smpl_mv,df_test)
Above is close but has not been tested. May require adjustment. I've had more trouble suggesting the parameter name in an ATTR() call than just leaving it out - hence the commented out ATTR() lines for ora.parameter_name.
Hope this helps someone who runs across this in the future.
In my Pl/Sql code , I have three variables v_var1 , v_operand , v_var2 whose values are populated based on some logic (v_var1 & v_var2 can be date , number , varchar. Associated Operand will be according to data type only). A sample would be
v_var1 = 10 , v_operand = '=' , v_var2 = 20.
Based on these value , I have to evaluate whether the condition "v_var1 -v_operand- v_var2"is true or false.
Ex :- with above values, I have to evaluate whether 10 equals 20 or not.
How can I achieve this ? Can I pass the whole string as '10 = 20' to some function and get the result as false?
One way I can think of is to write CASE statements for evaluating but can there be a better way ?
You could use dynamic SQL to do the evaluation as a filter on the dual table:
declare
v_var1 varchar2(10) := '10';
v_operand varchar2(10) := '=';
v_var2 varchar2(10) := '20';
l_result number;
begin
execute immediate 'select count(*) from dual where :var1 ' || v_operand || ' :var2'
into l_result using v_var1, v_var2;
if l_result = 1 then
dbms_output.put_line('True');
else
dbms_output.put_line('False');
end if;
end;
/
PL/SQL procedure successfully completed.
False
If the condition is true the count will get 1, otherwise it will get 0, and you can then test that via the local variable you select the count into.
Holding dates and numbers as strings isn't ideal, even temporarily, but might be OK as long as you convert to/from the real data types consistently, e.g. always explicitly converting dates with to_date and to_char and specifying the format masks.
There's the simplified version of my code who keep raise me ORA-06502:
declare
p_filter varchar2(300) := '2012';
p_value varchar2(300) := '12345.000';
w_new_value number(13,3) := null ;
w_count number(4) := null ;
BEGIN
SELECT count(*)
INTO w_count
FROM dual
where p_filter = p_filter;
--- more filters
if w_count != 0 then
w_new_value := p_value / w_count;
else
w_new_value := p_value;
end if;
-- do something
end;
/
Someone can give me a help?
DataBase Details
nls_language = italian
nls_territory = italy
nls_currency = �
nls_iso_currency = italy
nls_numeric_characters = ,.
nls_calendar = gregorian
nls_date_format = dd-mon-rr
nls_date_language = italian
nls_characterset = we8iso8859p15
nls_sort = west_european
nls_time_format = hh24:mi:ssxff
nls_timestamp_format = dd-mon-rr hh24:mi:ssxff
nls_time_tz_format = hh24:mi:ssxff tzr
nls_timestamp_tz_format = dd-mon-rr hh24:mi:ssxff tzr
nls_dual_currency = �
nls_nchar_characterset = al16utf16
nls_comp = binary
nls_length_semantics = byte
nls_nchar_conv_excp = false
First, this is always going return a value of 1.
SELECT count(*)
INTO w_count
FROM dual
It doesn't matter what the qualifier is.
Lastly, I just ran your simplified code example in Oracle 11R2 and it didn't throw an exception.
I added the following statement in place of your "do something" comment:
dbms_output.put_line('w_new_value: ' || w_new_value || '. w_count: ' || w_count);
The result was:
w_new_value: 12345. w_count: 1
So, I think you've simplified your example into oblivion. You need to provide something that actually shows the error.
Good luck.
I found myself the ansewer and i think is useful for other know.
The real problem of the script for my DB is the language.
The italian "version" of Oracle accept , instead of the . for translate the VARCHAR2 into NUMBER unlike the most of other country.
For make the code running well the solution is
w_new_value := replace(p_value,'.',',') / w_count;
This trick finally allows the DB use my VARCHAR2 param like a NUMBER
I know that NULLIF(X,Y) function of SQLITE work equivalent to:
CASE
WHEN
X = Y
THEN
NULL
ELSE
X
END
and IFNULL(X,Y) function work equivalent to:
CASE
WHEN
X IS NULL
THEN
Y
ELSE
X
END
IFNULL(X,Y) function of SQLITE is used for replacing the NULL values of X to the Y but I can't understand the use of NULLIF(X,Y) function of SQLITE.
Please explain with examples, so it is more useful.
The IFNULL function is used when the database contains NULL values, but you want to handle those values as something else; for example:
SELECT Name, IFNULL(Age, 'unknown') AS Age FROM People
The NULLIF function is used when the database contains special values that are not NULL, but that you want to handle as NULL.
This is useful especially for aggregate functions. For example, to get the number of employees that get bonuses, use:
SELECT COUNT(NULLIF(Bonus, 0)) FROM Employees
This is the same as:
SELECT COUNT(*) FROM Employees WHERE Bonus != 0
In practice, NULLIF is not used as often as IFNULL.
I use NULLIF() when UPDATing or INSERTing rows containing NULLable fieds.
Basically with PHP :
$value1 = 'foo';
$value2 = '';
$sql = 'INSERT INTO table(field1, field2) '
. "VALUES(NULLIF('$value1', ''), NULLIF('$value2', ''))";
// => INSERT INTO table(field1, field2) VALUES(NULLIF('foo', ''), NULLIF('', ''))
// => INSERT INTO table(field1, field2) VALUES('foo', NULL)
It saves me doing things like :
$value1forSQL = ($value1 === '' || $value1 === NULL) ? 'NULL' : "'$value1'";
...
$sql = ...
. "VALUES($value1forSQL, ...)";
I have a table "flags" containing flags with "name" and "value" where "name" is the name of the flag and "value" is either 'T' or 'F'
I would like to update a table based on a flag with name 'enable_feature' in the following manner:
BEGIN;
IF ((SELECT flags.value FROM flags WHERE flags.name = 'enable_feature') = 'T')
UPDATE... SET...;
ELSE
UPDATE... SET...;
END IF;
END;
My trouble seems to be in the IF statement. Specifically, i get the following error:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the
following:
( - + case mod new not null continue avg count current
exists max min prior sql stddev sum variance execute forall merge
time timestamp interval date pipe
How do I modify this statement such that I can perform an UPDATE/SET statement based on the value of 'enable_feature' (The UPDATE/SET statement is on a different table)
DECLARE
v flags.value%type;
BEGIN
SELECT flags.value into v FROM flags WHERE flags.name = 'enable_feature';
IF v = 'T' THEN
UPDATE... SET...;
ELSE
UPDATE... SET...;
END IF;
END;