In the oracle database there is a schema. Inside schema there is a package which contains different methods. How to retrieve the metadata of the procedure using getProcedureColumn() function in DatabaseMetaDataclass?
I have tried to get metadata using getProcedureColumns(catalog,schemaname,procedurename,columnnamepattern) it works fine when the procedure is located inside a schema. When a procedure is located inside a package in a schema it is not retrieving.
This will print out all the column information for a specific procedure in a package. Change parameters with real values.
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection ("jdbc:oracle:thin:#<server>:<port>:<sid>", "<username>", "<password>");
DatabaseMetaData metadata = conn.getMetaData();
String packageName = "<your package name>";
String schemaName = "<schema name>";
String procedureName = "<procedure name>";
ResultSet rs = metadata.getProcedureColumns(
packageName,
schemaName,
procedureName,
"%");
while(rs.next()) {
// get stored procedure metadata
String procedureCatalog = rs.getString(1);
String procedureSchema = rs.getString(2);
procedureName = rs.getString(3);
String columnName = rs.getString(4);
short columnReturn = rs.getShort(5);
int columnDataType = rs.getInt(6);
String columnReturnTypeName = rs.getString(7);
int columnPrecision = rs.getInt(8);
int columnByteLength = rs.getInt(9);
short columnScale = rs.getShort(10);
short columnRadix = rs.getShort(11);
short columnNullable = rs.getShort(12);
String columnRemarks = rs.getString(13);
System.out.println("stored Procedure name="+procedureName);
System.out.println("procedureCatalog=" + procedureCatalog);
System.out.println("procedureSchema=" + procedureSchema);
System.out.println("procedureName=" + procedureName);
System.out.println("columnName=" + columnName);
System.out.println("columnReturn=" + columnReturn);
System.out.println("columnDataType=" + columnDataType);
System.out.println("columnReturnTypeName=" + columnReturnTypeName);
System.out.println("columnPrecision=" + columnPrecision);
System.out.println("columnByteLength=" + columnByteLength);
System.out.println("columnScale=" + columnScale);
System.out.println("columnRadix=" + columnRadix);
System.out.println("columnNullable=" + columnNullable);
System.out.println("columnRemarks=" + columnRemarks);
}
Related
I have created a stored procedure that returns a create table sql statement; I want to be able to now call that procedure and assign the result to a variable like:
set create_table_statement = call sp_create_stage_table(target_db, table_name);
snowflake will not let me do this, so is there a way I can.
Context
We have just been handed over our new MDP which is built on AWS-S3, DBT & Snowflake, next week we go into production but we have 200+ tables and snowlpipes to code out. I wanted to semi automate this by generating the create table statements based off the tables metadata and then calling the results from that to create the tables. At the moment we're having to run the SQL, copy+paste the results in and then run that, which is fine in dev/pre-production mode when it's a handful of tables. but with just 2 of us it will be a lot of work to get all those tables and pipes created.
so I've found a work around, by creating a second procedure and calling the first one as a se=ql string to get the results as a string - then calling that string as a sql statement. like:
create or replace procedure sp_create_stage_table("db_name" string, "table_name" string)
returns string
language javascript
as
$$
var sql_string = "call sp_get_create_table_statement('" + db_name + "','" + table_name + "');";
var get_sql_query = snowflake.createStatement({sqlText: sql_string});
var get_result_set = get_sql_query.execute();
get_result_set.next();
var get_query_value = get_result_set.getColumnValue(1);
sql_string = get_query_value.toString();
try {
var main_sql_query = snowflake.createStatement({sqlText: sql_string});
main_sql_query.execute();
return "Stage Table " + table_name + " Successfully created in " + db_name + " database."
}
catch (err){
return "an error occured! \n error_code: " + err.code + "\n error_state: " + err.state + "\n error_message: " + err.message;
}
$$;
It is possible to assign scalar result of stored procedure to session variable. Instead:
SET var = CALL sp();
The pattern is:
SET var = (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())));
Sample:
CREATE OR REPLACE PROCEDURE TEST()
RETURNS VARCHAR
LANGUAGE SQL
AS
BEGIN
RETURN 'Result from stored procedrue';
END;
CALL TEST();
SET variable = (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())));
SELECT $variable;
-- Result from stored procedrue
Question is related to Snowflake and Snowsql. That said I'm trying to within a stored proc create a temp table and then 'copy into' this temp table from azure blob storage.
I'm manually executed the snow sql statements and they work fine.
Statement 1:CREATE TEMPORARY TABLE DB.TABLES.LINE_DETAILS_INCREMENTAL LIKE DB.TABLES.LINE_DETAILS;
Statement 2:
COPY INTO DB.TABLES.LINE_DETAILS_INCREMENTAL FROM (SELECT * FROM #DB.BASE.Azure/S/LINE_DETAILS_INCREMENTAL )
force = false file_format = (type = csv field_delimiter = '|' encoding = 'Windows 1252' skip_header = 0);
But when I encapsulate this into a stored proc and try to run it it gives error:-
"JavaScript compilation error: Uncaught SyntaxError: Unexpected identifier in SP_DELETE_LINE_DETAILS at ' var insert_clause = 'COPY INTO DB.TABLES.LINE_DETAILS_INCREMENTAL FROM (SELECT * FROM #Feeds_DB.BASE.Azure/S/LINE_DETAILS_INCREMENTAL ) force = true file_format = (type = csv field_delimiter = '|' encoding = 'Windows1252' skip_header = 0) On_error = continue;'' position 288 ".
Code of the stored proc is:-
CREATE or replace procedure "DB"."TABLES"."SP_DELETE_INSERT_3DAYS_INTO_LINE_DETAILS"()
returns varchar(1000)
language javascript
as
$$
try{
var create_clause = 'CREATE TEMPORARY TABLE DB.TABLES.LINE_DETAILS_INCREMENTAL LIKE DB.TABLES.PS_TRANSACTION_LINE_DETAILS;'
var create_stmt = snowflake.createStatement({sqlText: create_clause});
var create_res = create_stmt.execute();
var insert_clause = 'COPY INTO DB.TABLES.LINE_DETAILS_INCREMENTAL FROM (SELECT * FROM #Tableau_Feeds_DB.BASE_TABLES.JDAStagingAzure/POS/PS_TRANSACTION_LINE_DETAILS_INCREMENTAL ) force = true file_format = (type = csv field_delimiter = '|' encoding = 'Windows1252' skip_header = 0) On_error = continue;'
var insert_stmt = snowflake.createStatement({sqlText: insert_clause});
var insert_res = insert_stmt.execute();
var select_clause = 'select distinct TO_CHAR(TO_DATE(CREATE_DATE)) as CREATE_DATE from DB.TABLES.LINE_DETAILS_INCREMENTAL order by CREATE_DATE';
var select_stmt = snowflake.createStatement({sqlText: select_clause});
var select_res = select_stmt.execute();
while (select_res.next())
{
date_ip = select_res.getColumnValue(1);
var desc_user_sql = `delete from DB.TABLES.LINE_DETAILS where TO_DATE(CREATE_DATE) = :1;`
var desc_user_stmt = snowflake.createStatement({sqlText: desc_user_sql, binds: [date_ip]});
var desc_user_sql2 = `INSERT INTO DB.TABLES.PS_TRANSACTION_LINE_DETAILS select * from DB.TABLES.PS_TRANSACTION_LINE_DETAILS_INCREMENTAL where TO_DATE(CREATE_DATE) = :1;`
var desc_user_stmt2 = snowflake.createStatement({sqlText: desc_user_sql2, binds: [date_ip]});
try{
desc_user_stmt.execute();
desc_user_stmt2.execute();
}
catch(err)
{
return "Error inserting records: " +err;
}
}
return "Data has been insert in success!";
}
catch(err){
return "Error whileselecting Roles : " +err;
}
return 0;
$$
I think the issue you have here is that you're using single quote marks both to start/end your string, and within the string itself.
For example, you have the following phrase in your string:
encoding = 'Windows1252'
I would suggest escaping the additional quotation marks with a backslash, like so:
encoding = \'Windows1252\'
Do this for all additional quotation marks and you should be fine.
Let me know if you still face issues after!
Try changing single quotes as below
var insert_clause = `COPY INTO DB.TABLES.LINE_DETAILS_INCREMENTAL FROM (SELECT * FROM #Tableau_Feeds_DB.BASE_TABLES.JDAStagingAzure/POS/PS_TRANSACTION_LINE_DETAILS_INCREMENTAL ) force = true file_format = (type = csv field_delimiter = '|' encoding = 'Windows1252' skip_header = 0) On_error = continue;`
https://docs.snowflake.com/en/sql-reference/stored-procedures-usage.html#line-continuation
I have a stored procedure in SQL Server 2012:
CREATE PROCEDURE GetImmediateManager
#managerID INT OUTPUT
AS
BEGIN
SET #managerID = 6;
SELECT *
FROM Roles;
END
When I remove select * from Roles; the output value (#managerID) is returned correctly to my C# code. But when the procedure has select * .., the value returned by output parameter is null.
How can I return select and output at the same time?
In C# my code looks like this:
dbContext.Database.OpenConnection();
DbCommand cmd = dbContext.Database.GetDbConnection().CreateCommand();
cmd.CommandTimeout = 15;
cmd.CommandText = "GetImmediateManager";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
var rowsCountParam = new SqlParameter("#managerID", System.Data.SqlDbType.Int);
rowsCountParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(rowsCountParam);
using (var reader = cmd.ExecuteReader())
{
tasks = reader.MapToList<TaskManagerTask>();
//rowsCount = (int)rowsCountParam.Value;
}
The simplistic answer is to add #managerID to your select statement
For a less simplistic perhaps the following, I changed the names a bit to reflect the use, get parameter after it closes.
var managerIDParam = new SqlParameter("#managerID", System.Data.SqlDbType.Int);
managerIDParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(managerIDParam);
using (var reader = cmd.ExecuteReader())
{
tasks = reader.MapToList<TaskManagerTask>();
}
int managerIDParamUsed = (int)managerIDParam.Value;
**My Oledb source code is-
When adding second parameter it overrides first. how to solve?**
IDTSComponentMetaData100 Source = PopulateEtlDataSourceDetailDFT.ComponentMetaDataCollection.New();
Source.ComponentClassID = "DTSAdapter.OleDbSource";
CManagedComponentWrapper srcDesignTime = Source.Instantiate();
srcDesignTime.ProvideComponentProperties();
Source.Name = "OLEDB Source";
//Assigning Connection manager
Source.RuntimeConnectionCollection[0].ConnectionManagerID = Config.ID;
Source.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(Config);
// Set the custom properties of the source.
srcDesignTime.SetComponentProperty("AccessMode", 2);
Guid variableGuid = new Guid(ETLSourceRunId.ID);
String ParamProperty = #"""#OrganizationName"",{" + variableGuid.ToString().ToUpper() + #"};";
srcDesignTime.SetComponentProperty("ParameterMapping", ParamProperty);
Guid variableGuid1 = new Guid(Parent_ETLSourceRunId.ID);
String ParamProperty1 = #"""#SourceRunID"",{" + variableGuid.ToString().ToUpper() + #"};";
srcDesignTime.SetComponentProperty("ParameterMapping", ParamProperty1);
srcDesignTime.SetComponentProperty("SqlCommand","EXEC [dbo].[USP_GetCustomerEtlSourceDetailRecordSet] #OrganizationName=?,#SourceRunID=?");
srcDesignTime.AcquireConnections(null);
srcDesignTime.ReinitializeMetaData();
srcDesignTime.ReleaseConnections();
1. How to add multiple parameters to oledb source? and
2. how to add project parameters to oledb source?
I'm no pro at c#, but:
Guid variableGuid = new Guid(ETLSourceRunId.ID);
String ParamProperty = #"""#OrganizationName"",{" + variableGuid.ToString().ToUpper() + #"};";
srcDesignTime.SetComponentProperty("ParameterMapping", ParamProperty);
Guid variableGuid1 = new Guid(Parent_ETLSourceRunId.ID);
String ParamProperty1 = #"""#SourceRunID"",{" + variableGuid.ToString().ToUpper() + #"};";
srcDesignTime.SetComponentProperty("ParameterMapping", ParamProperty1);
2nd from last line:
String ParamProperty1 = #"""#SourceRunID"",{" + variableGuid.ToString().ToUpper() + #"};";
shouldn't it be variableGuid1.ToString().Upper() and not variableGuid.ToString().Upper() since you're assigning the value as:
Guid variableGuid1 = new Guid(Parent_ETLSourceRunId.ID);
Try using SQL command from variable as data access mode. Create an variable as string and set it's value to your SqlCommand. If you SqlCommand needs multiple parameters, then again create variables to store those values and use these variables in SqlCommand variable value.
You can follow this article to start with.
Steps
1) Create variable for SqlCommand
strVarSqlCommand = "EXEC [dbo].[USP_GetCustomerEtlSourceDetailRecordSet] #OrganizationName=strVarOrgName ,#SourceRunID=strVarSrcRunId"
2) create variables to refer in Sqlcommand variable
strVarOrgName = "XXX"
strVarSrcRunId="YYY"
As per your requirement, you can set values to these variable as hard coded or dynamically as well.
3) Use strVarSqlCommand variable in ole db source where data access mode is command with variable
I am having problem in updating database from xml and dynamic query.
Exec('UPDATE ' + #DbInstance + 'dbo.tblAcademic
SET tblacademic.RollNo = XMLAcademic.Item.value(''#RollNo'', ''VARCHAR(50)''),
tblacademic.Board = XMLAcademic.Item.value(''#Board'', ''VARCHAR(150)''),
tblacademic.PassingYear = XMLAcademic.Item.value(''#PassingYear'', ''VARCHAR(10)''),
tblacademic.Semester = XMLAcademic.Item.value(''#Semester'', ''VARCHAR(5)''),
tblacademic.MarksObt = XMLAcademic.Item.value(''#MarksObt'', ''varchar(9)''),
tblacademic.MaxMarks = XMLAcademic.Item.value(''#MaxMarks'', ''int'')
FROM ''' + Convert(varchar, #XMLEducationalDetail) + '''.nodes(''/root/row'') AS XMLAcademic(Item)
WHERE tblacademic.AcademicID = XMLAcademic.Item.value(''#AcademicID'', ''int'')')
This is showing error at Convert function and without convert function there is also execution error showing xml to nvarchar error.