Oracle SQL: create a dumy table from a substitution variable - sql

In Oracle SQL, I can create a dummy table thanks to the code shown below:
select crca.*
from my_real_table real_table,
table(ntde.ENCRYPT_ALL(:inputParam)) enc
where
...
I would like to be able to do same thing without using ntde.ENCRYPT_ALL, I would like to do something like that:
select crca.*
from my_real_table real_table,
table(:inputParam) enc
where
...
It does not work and I get this error:
00000 - "cannot access rows from a non-nested table item"
*Cause: attempt to access rows of an item whose type is not known at
parse time or that is not of a nested table type
*Action: use CAST to cast the item to a nested table type
Do you know how to do that please?

As the exception says, use CAST:
SELECT c.*
FROM my_real_table r
CROSS JOIN TABLE( CAST(:inputParam AS your_collection_type) ) c
This assumes that:
the bind variable contains an collection (and not a string); and
the bind variable is being passed from an application (this is a Java example); and
you have created an SQL collection type to cast the bind variable to. For example:
CREATE TYPE your_collection_type AS TABLE OF NUMBER;
Or, instead of creating your own collection type, you could use a built in collection (or VARRAY) such as SYS.ODCIVARCHAR2LIST.

Related

In Oracle, what does [select * from table()] mean?

I am trying to search for information on this topic in sql but search is not showing me results.
SELECT * FROM TABLE(package/procedure/function);
Which topic does the above sql statement come under? Can I have a link to a doc?
The TABLE collection expression is described here in the Oracle documentation.
In short, it is used to convert a collection or pipelined function into a table that can be queried by a SELECT statement.
Typically, the collection must be of a datatype that is defined at the database level (i.e. a datatype that was created by a create or replace type ... statement).
e.g.
select *
from table(sample_pkg.func_that_rtrns_array);

PostgreSQL - How to cast dynamically?

I have a column that has the type of the dataset in text.
So I want to do something like this:
SELECT CAST ('100' AS %INTEGER%);
SELECT CAST (100 AS %TEXT%);
SELECT CAST ('100' AS (SELECT type FROM dataset_types WHERE id = 2));
Is that possible with PostgreSQL?
SQL is strongly typed and static. Postgres demands to know the number of columns and their data type a the time of the call. So you need dynamic SQL in one of the procedural language extensions for this. And then you still face the obstacle that functions (necessarily) have a fixed return type. Related:
Dynamically define returning row types based on a passed given table in plpgsql?
Function to return dynamic set of columns for given table
Or you go with a two-step flow. First concatenate the query string (with another SELECT query). Then execute the generated query string. Two round trips to the server.
SELECT '100::' || type FROM dataset_types WHERE id = 2; -- record resulting string
Execute the result. (And make sure you didn't open any vectors for SQL injection!)
About the short cast syntax:
Postgres data type cast

SQL temp table creation with parameter in FastReport VCL 5

since several request in my report use the same subquery, I wrote a DBXQuery named qCreateTemp that prepares a temporary table:
CREATE TEMP TABLE temp AS SELECT * FROM acomplexrequest WHERE afield = :avalue
I defined avalue as an (integer) parameter of the request with value.
First I linked it to a dummy MasterData band, but FastReports complains the request doesn't return a Cursor.
So I tried to call it explicitly from the script code, first simply as:
qCreateTemp.ExecSQL;
Then noticing the request's parameter was not passed, I tried:
qCreateTemp.Params.ParamByName('avalue').Value := <avariable>;
qCreateTemp.ExecSQL;
but I get an error "Could not convert a variant of type (Null) into type (Integer)"
What's the best/correct way to do this ? Thanks !

Create Table from View - Oracle SQL SQL Error: ORA-01723: zero-length columns are not allowed

I need to create a table from view with statement like
CREATE TABLE NEW_TABLE AS
SELECT *
from VIEW
It is giving error message as below. It is not possible to create table from view (with Select * statement)?
Error report -
SQL Error: ORA-01723: zero-length columns are not allowed
01723. 00000 - "zero-length columns are not allowed
I have this problem when NULL is specified for a column, but the type is not specified. Arrgh!
You will need to look at the code. This often happens when I use:
select '' as x
Because I think '' should have the right type.
In any case, the solution is simple:
select cast(NULL as varchar2(255)),
cast(NULL as number)
or whatever the type is.
You'll need to either change the view definition, or use a query with a subquery with explicit casts.

passing an array into oracle sql and using the array

I am running into the following problem, I am passing an array of string into Oracle SQL, and I would like to retrieve all the data where its id is in the list ...
here's what i've tried ...
OPEN O_default_values FOR
SELECT ID AS "Header",
VALUE AS "DisplayValue",
VALUE_DESC AS "DisplayText"
FROM TBL_VALUES
WHERE ID IN I_id;
I_id is an array described as follows - TYPE gl_id IS TABLE OF VARCHAR2(15) INDEX BY PLS_INTEGER;
I've been getting the "expression is of wrong type" error.
The I_id array can sometimes be as large as 600 records.
My question is, is there a way to do what i just describe, or do i need to create some sort of cursor and loop through the array?
What has been tried - creating the SQL string dynamically and then con-cat the values to the end of the SQL string and then execute it. This will work for small amount of data and the size of the string is static, which will caused some other errors (like index out of range).
have a look at this link: http://asktom.oracle.com/pls/asktom/f?p=100:11:620533477655526::::P11_QUESTION_ID:139812348065
effectively what you want is a variable in-list with bind variables.
do note this:
"the" is deprecated. no need for it
today.
TABLE is it's replacement
select * from TABLE( function );
since you already have the type, all you need to do is something similar to below:
OPEN O_default_values FOR
SELECT ID AS "Header",
VALUE AS "DisplayValue",
VALUE_DESC AS "DisplayText"
FROM TBL_VALUES
WHERE ID IN (select column_value form table(I_id));