Sometimes it happens that I have some errors in stored procedure body, e.g.
select invalidColumn from validTable
When I try to create/alter stored procedure, it works and I can see the error only when I try to execute the stored procedure.
Is it possible to force schema check when I create or alter?
Need to get list of fields produced by a stored procedure. But it needs to not execute the stored procedure at that time.
The stored procedure may be destructive.
The stored procedure may use temporary tables.
The stored procedure may use cursors.
SET FMTONLY ON; doesn't work with temporary tables.
SET NOEXEC ON; doesn't work as it doesn't return a field list.
I'm limited it what I can do with the stored procedures, but I could request that all temporary tables be enclosed with something like:
CREATE PROCEDURE [dbo].[Test_PSH]
AS
BEGIN
SELECT * INTO #PSH_Temp FROM dbo.SomeTable
IF OBJECT_ID('tempdb..#PSH_Temp) IS NOT NULL
BEGIN
~~DO SOME CHANGES~~
SELECT * FROM #PSH_Temp
DROP TABLE #PSH_Temp
END
ELSE
SELECT * FROM dbo.SomeTable WHERE 1 = 0
END
But even this attempt at working around the SET FMTONLY ON; didn't work.
And it would be best if I could avoid any and all changes to the stored procedures. Not been able to find a workable solution so far.
Thank you in advanced.
According to books online (https://technet.microsoft.com/en-us/library/ms189915(v=sql.105).aspx) we have:
In SQL Server, if the current schema contains a procedure with the specified name, that procedure is returned. If a nonqualified stored procedure is specified, the Database Engine searches for the procedure in the following order:
• The sys schema of the current database.
• The caller's default schema if executed in a batch or in dynamic SQL; or, if the non-qualified procedure name appears inside the body of another procedure definition, the schema containing this other procedure is searched next.
• The dbo schema in the current database.
I tried testing the case with a stored procedure Proc1 which calls proc2. I define them in the same schema, but call proc2 without the schema name. It doesn't work, so what does the second part of item two on the list above mean?
Use AdventureWorks
GO
CREATE SCHEMA MySchema
GO
CREATE PROCEDURE MySchema.PROC2
AS
BEGIN
SELECT 1
END
GO
CREATE PROCEDURE MySchema.PROC1
AS
BEGIN
SELECT 2
-- calling proc2 without schema name
-- expecting it will work, since proc1 and proc2 are in same schema
EXEC PROC2
END
GO
--calling proc1 (my default schema is dbo)
--Could not find stored procedure 'PROC2'.
EXEC MySchema.PROC1
I know best practice is to always use the schema name - I'm just curious what they mean by the second item. I've tested this on version 2016.
The page you have linked to is the documentation for a specific system stored procedure. Its meaning is limited to what this stored procedure does.
CREATE PROCEDURE MySchema.PROC1
AS
BEGIN
SELECT 2
-- calling proc2 without schema name
-- expecting it will work, since proc1 and proc2 are in same schema
EXEC sp_stored_procedures 'PROC2'
END
Produces 2 result sets - the first contains 2, the second contains information about the MySchema.PROC2 stored procedure.
I am trying to create a stored procedure and I am so lost. I have included what I have done so far, but I know for sure I am missing a few things and can't figure it out. please help!
Question I am trying to solve:
Obtain the name and credit limit of the customer whose number currently stored in I_customer_num. place these values in the variables I_customer_name and I_credit_limit. Output the content of I_customer_name and I_credit_limit.
CREATE PROCEDURE USP_DISP_NAME_CREDIT
#CUSTOMERNUM char(3)
AS
SELECT CUSTOMER_NAME, CREDIT_LIMIT
FROM CUSTOMER
WHERE CUSTOMER_NUM = #CUSTOMERNUM
this is the way its done in sql server:
CREATE PROCEDURE <Procedure_Name, sysname, ProcedureName>
<#Param1, sysname, #p1>
AS
BEGIN
SET NOCOUNT ON;
SELECT .......................
END
GO
also if you are using sql-server go to your database then programmability then in stored procedures right click then click on new stored procedure
I'd like to create users through procedure on another database via database link.I am getting error while executing procedure.
Here are the code which i used.
create or REPLACE PROCEDURE hostname
(host_name in varchar2,user_name in VARCHAR2, pass_word in VARCHAR2,
table_space in varchar2,pro_file in varchar2)
as
db_link_name varchar2(30);
begin
select db_link into db_link_name from all_db_links where host=host_name;
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement#'||db_link_name||('CREATE USER '||user_name||' IDENTIFIED BY '||pass_word||'
DEFAULT TABLESPACE '||table_space||' PROFILE '|| pro_file||' ACCOUNT UNLOCK');
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement#'||db_link_name||
('GRANT CONNECT,RESOURCE,EXECUTE_CATALOG_ROLE,Create table,create session,create view,create sequence,create procedure,create job,create synonym TO '||user_name);
end;
/
execute hostname('orcl1','rahul1','rahul','users','default');
Error: ORA-00900: invalid SQL statement ORA-06512: at
"SYS.HOSTNAME", line 6 ORA-06512: at line 1
00900. 00000 - "invalid SQL statement"
*Cause:
*Action:
I think you may have got a little confused by some of the advice provided by the commenter mustaccio. What he meant to say is that the SQL strings in your EXECUTE IMMEDIATE statements need to use PL/SQL blocks in order to call stored procedures.
In other words, instead of writing
EXECUTE IMMEDIATE 'dbms_utility.exec_ddl_statement ... ';
you should write
EXECUTE IMMEDIATE 'BEGIN dbms_utility.exec_ddl_statement ... ; END;';
For your procedure, I would recommend doing introducing a local variable for the strings you are passing to EXECUTE IMMEDIATE. These can be notoriously tricky to get right, and if you've assigned them to a local variable you can easily output them using dbms_output.put_line. In fact, I did exactly this while fixing up the problems in your procedure. I would recommend continuing to do this if you wish to modify or extend your procedure.
Anyway, here's what I ended up with, which appeared to work:
create or REPLACE PROCEDURE hostname
(host_name in varchar2,user_name in VARCHAR2, pass_word in VARCHAR2,
table_space in varchar2,pro_file in varchar2)
as
db_link_name varchar2(30);
l_ddl_sql varchar2(4000);
begin
select db_link into db_link_name from all_db_links where host=host_name;
l_ddl_sql := 'begin dbms_utility.exec_ddl_statement#'||db_link_name||'(''CREATE USER '||user_name||' IDENTIFIED BY '||pass_word||'
DEFAULT TABLESPACE '||table_space||' PROFILE '|| pro_file||' ACCOUNT UNLOCK''); END;';
EXECUTE IMMEDIATE l_ddl_sql;
l_ddl_sql := 'begin dbms_utility.exec_ddl_statement#'||db_link_name||
'(''GRANT CONNECT,RESOURCE,EXECUTE_CATALOG_ROLE,Create table,create session,create view,create sequence,create procedure,create job,create synonym TO '||user_name || '''); END;';
EXECUTE IMMEDIATE l_ddl_sql;
end;
/