How do I create Oracle Type which refers to table columns for data type? - sql

I am trying to define a type using the following code.
CREATE OR REPLACE TYPE MY_TYPE AS OBJECT (
app_id some_table_name.app_id%type
);
If I run this, I get the error.
Error(4,32): PLS-00201: identifier 'some_table_name.app_id' must be declared
What is wrong with this?

What's wrong with it is that %type is PL/SQL syntax. It isn't supported in SQL. Now we use PL/SQL to define Types (especially member functions, constructors, etc) but the Types themselves are SQL objects, and so follow SQL rules. That means we must declare Type attributes with explicit datatypes.
I agree that's a shame, and it would be really neat if we could reference table columns in type declarations like this. Unfortunately Oracle have really slowed down the changes to their TYPE implementation over the last couple of versions, so I think it is unlikely this will change in the near future.
What I would really like to see is Oracle support this syntax:
CREATE OR REPLACE TYPE MY_TYPE AS OBJECT
( one_row some_table_name.%rowtype );
Dynamic objects for interfaces: how cool would that be?

You cannot use some_table_name.app_id%type when declaring a type in the database, any more than you can do this:
create table emp (empno number,
deptno dept.deptnp%type, -- NOT ALLOWED
);
You must use either a built-in type such as NUMBER, VARCHAR2(10) or a user-defined type such as mytype

Related

Snowflake schema and table reference in User Defined Function arguments

I'm trying to create a User Defined Function (UDF) in Snowflake where the arguments can take in schema, table, and column values as variables so that the function can dynamically call different tables. I tried to do this and save the function but Snowflake threw an error saying that the schema name did not exist - it tried to look for the schema using the argument name rather than the variable that will be entered into the function arguments.
Here is an example of what I'm trying to do:
CREATE OR REPLACE FUNCTION "DB_NAME"."SCHEMA_NAME"."FUNCTION_NAME"(
SCHEMA_VAR VARCHAR,
TABLE_VAR VARCHAR,
COLUMN_VAR VARCHAR)
RETURNS TABLE (RETURN_COL VARCHAR)
AS
$$
SELECT COLUMN_VAR FROM "DB_NAME".SCHEMA_VAR.TABLE_VAR
$$;
What you are describing is dynamic SQL which is only allowed from a stored procedure, not a function.
From normal SQL you can use a TABLE LITERAL to have dynamical named tables from the perspective of your code running the SQL, but then you can also just do string manipluation in your code, but this method makes it injection safe.
Honestly, even if what you're trying to achieve was doable using a UDF, it's an overkill. Consider below
set (table_name, column_name) = ('mydb.myschema.mytable', 'mycolumn');
select $column_name
from identifier($table_name);

Syntax error at or near "TYPE" in Postgresql

Hi I was trying to create Type but getting a Syntax error while doing it.
CREATE OR REPLACE TYPE ARR_HNW_ID AS VARRAY(50) OF INTEGER;
Can you please help me to resolve this Issue
I don’t believe OR REPLACE is valid syntax. You can CREATE or ALTER types but not REPLACE
Thera are multiple mistakes in your SQL:
There is no CREATE OR REPLACE TYPE syntax in PostgreSQL- take a look into docs;
There is no type VARRAY in postgresql. If you need an array of integer just declare it like integer[].
What you are creating here is not a type but a DOMAIN.
So basically you can simply use integer[] for your ARR_HNW_ID

Which limitiations exist in using ORACLE CUSTOM DATA TYPES as parameter in PL/SQL Stored Procedures?

I'm involved in a pair of java project in which are used oracle stored procedures using oracle custom data type, for example ORACLE OBJECT
CREATE OR REPLACE TYPE OBJ1 AS OBJECT(
SOME_VALUE VARCHAR2(18 CHAR)
, SOME_OTHER_VALUE NUMBER(3,0)
, ...
);
/
and ORACLE TABLE containg these OBJECTS
CREATE OR REPLACE TYPE TBL1 IS TABLE OF OBJ1;
/
So the Stored Procedures receive the ORACLE TABLE as parameter, something like this:
CREATE OR REPLACE PACKAGE PKG_SECURITY_CHECK AS
PROCEDURE VERIFY1(
TBL_INPUT TBL1,
SOME_OUTPUT OUT NUMBER
);
END PKG_CIRCUITO_DI_SICUREZZA;
I'm wondering if there are limitations for example in the number of columns of the ORACLE OBJECT, or in the number of ORACLE OBJECT that could be contained inside the ORACLE TABLE, when the TABLE is passed as parameter...?
I see some other question about parameter numbers or parameter size permitted, put are general question about simple data type as varchar2 or number, I did not find something specific for ORACLE CUSTOM DATA TYPES as parameter in STORED PROCEDURES.
There are no additional structural limitations. Providing it's a valid Oracle type - we can create it in SQL - we can use it to define a PL/SQL parameter.
There no numerical limits to the number of instances of OBJ1 you can store in TBL1. However, objects are stored in session memory, so there is a ceiling, depending on how many populated attributes the object has. However, if you're stuffing so many objects into a collection you blow the MAX_PGA_TARGET that's a sign you've probably chosen the wrong approach.

What is the meaning of the FORCE keyword in a CREATE OR REPLACE TYPE statement?

What does the keyword FORCE mean in this statement:
CREATE OR REPLACE TYPE object_name FORCE IS TABLE OF NUMBER;
It means forcing (re)creation of the type, even if it has other type dependencies. For instance, if you have these types:
type O_Object is (
Prop1 INT,
Prop2 INT
);
type T_ObjectTable is table of O_Object;
If you would like to modify O_Object, you will get an error, because T_ObjectTable depends on it. Using FORCE, you can recreate the object (though T_ObjectTable will need recompiling afterwards).
This won't work though if there are table dependencies (actual tables, not table-of-object types). In that case, the create statement will fail with or without FORCE.
It's in the docs too :)

How to use Teradata structured UDT

I have to create a structured User Defined Type and use it as routine's parameters datatype in Teradata.
So I've created the following UDT
create type sysudtlib.person as(ssn character(11),first_name varchar(20)) not final;
However, wherever I try to use the created UDT, either in table DDL or in stored procedure
create table twm_source.test_udt(purchase_id int, customer sysudtlib.person);
create procedure twm_source.sp_test_udt(in p1 sysudtlib.person)
begin
insert into tbl_udt values(p1.ssn, p1.first_name);
end;
I get the same error:
User-defined Transform is not defined for UDT 'person' .
It looks like I have to add a definition of the UDT-GroupName to the DBC.UDTTRANSFORM dictionary table.
Could anyone please provide some brief but vivid example of code that illustrates how to do so. Just something I need to do in order to get my structured UDT ready for use.
Any help is greatly appreciated.