SQL Server - Unable to put comments in procedure - sql

If I create procedure
/*
This comment does will disappear
*/
CREATE PROCEDURE [dbo].[test_123]
AS
BEGIN
/*
This comment does will disappear
*/
--This comment does will disappear
SELECT 1 AS Test
END
On my instance of the DB creates it like this
CREATE PROCEDURE [dbo].[test_123]
AS
BEGIN
SELECT 1 AS Test;
END
Running it in a different DB I get the expected result.
What caused the comments to disappear?
Useful info : I have the RedGate tool-belt installed (maybe it could be related)
I'm running SQL Server 14.0.2027.2

Related

Stored procedure for writing back to db2 database

Im new to db2 stored procedure, im approaching here for some help/guidance.
I have users who access cognos for reporting.
Recently I got a requirement from one of our clients for writing back to the db2 table based on user provided comment or input through IBM cognos.
I tried below code in db2 and cognos, but it works half way.
The catch is whenever a user provides a fresh entry it gets stored quickly but whenever a user tries to update the same entry, it takes almost 15-20 mins to refresh that record at table level. I won't understand what i can improve on my code here.
create procedure ngetl.new_update_comment (
in #p_job_status_summary_key integer
,in #p_comment varchar(4000)
,in #p_modified_by varchar(25)
)
dynamic result sets 1
begin
declare e1 cursor with return for
select 1
from ngetl.job_status_summary
where job_status_summary_key = 17076
with ur;
if upper(#p_modified_by) like '%IBM%'
or upper(#p_modified_by) like 'V%' then
update ngetl.job_status_summary
set ibm_comment = #p_comment
,modified_by_ibm = #p_modified_by
,timestamp_ibm = current_timestamp
where job_status_summary_key = #p_job_status_summary_key;
else update ngetl.job_status_summary
set sbi_comment = #p_comment
,modified_by_sbi = #p_modified_by
where job_status_summary_key = #p_job_status_summary_key;
end if;
commit;
open e1;
end

Cannot create new procedure in SQL manager lite

I am working with SQL manager lite for Interbase/Firebird application. I have downloaded firebird database, successfully connected to that database and its host, but now I want to create procedure.
I couldn't done it via tutorials, so I decided to just click New->Procedure and do that automatically. But doing this way I still have errors.
My code what I have tried without clicking New->Procedure:
CREATE PROCEDURE MyProc
AS
SELECT M_DOKUMENTY.NDZIEN FROM M_DOKUMENTY WHERE M_DOKUMENTY.SRODZAJ = '1234'
GO;
The code which was generated using New->Procedure wizard:
CREATE PROCEDURE SHOW_ALL
AS
BEGIN
/* Procedure body */
SELECT
M_DOKUMENTY.NDZIEN,
M_DOKUMENTY.CKIERUNEK,
M_DOKUMENTY.CMEDIUM FROM M_DOKUMENTY WHERE M_DOKUMENTY.SRODZAJ = '1234'
SUSPEND;
END;
But when I am clicking that lightning icon (compile) it complains about error:
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 9, column 3.
SUSPEND.
How to fix that?
Screenshot of error in SQL Manager lite
The problem is that your syntax is wrong. You need to define the output parameters, and you need to use either select ... into <list of variables> to select a single row, or for select ... into <list of variables> do to loop over multiple rows.
Your stored procedure should be something like:
CREATE PROCEDURE SHOW_ALL
RETURNS (NDZIEN varchar(50), CKIERUNEK varchar(50), CMEDIUM varchar(50))
AS
BEGIN
/* Procedure body */
for SELECT
M_DOKUMENTY.NDZIEN,
M_DOKUMENTY.CKIERUNEK,
M_DOKUMENTY.CMEDIUM
FROM M_DOKUMENTY
WHERE M_DOKUMENTY.SRODZAJ = '1234'
into :NDZIEN, :CKIERUNEK, :CMEDIUM
do
SUSPEND;
END
If your select only produces a single row, then you could also consider using
CREATE PROCEDURE SHOW_ALL
RETURNS (NDZIEN varchar(50), CKIERUNEK varchar(50), CMEDIUM varchar(50))
AS
BEGIN
/* Procedure body */
SELECT
M_DOKUMENTY.NDZIEN,
M_DOKUMENTY.CKIERUNEK,
M_DOKUMENTY.CMEDIUM
FROM M_DOKUMENTY
WHERE M_DOKUMENTY.SRODZAJ = '1234'
into :NDZIEN, :CKIERUNEK, :CMEDIUM;
SUSPEND;
END
Notice the ; after the into clause. In this case you could also leave out the SUSPEND;. That will make the stored procedure executable instead of selectable. Depending on how you want to use it, that could be a better choice.
See the Firebird documentation on created stored procedures and its procedural SQL language for more information.

DB2 Select Statement error after for loop in stored procedure

I've written a stored procedure which uses a for loop to execute a query for a list of views. It generates a dynamic sql statement for each view inside the for loop and then executes it, which inserts output into a declared temporary table.
The for loop works perfectly and it runs without errors, however if I add a select statement after the END FOR; to get the final output from the temporary table I get the error below. Does anyone have any ideas please?
Error 16/07/2018 10:43:41 0:00:00.007 DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "select *" was found following "1; END FOR; ". Expected tokens may include: "<call>". LINE NUMBER=31. SQLSTATE=42601
SQL Code:
BEGIN
DECLARE SQLTEXT varchar(500);
DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS(
temp table columns
);
FOR v as cur1 cursor for
select distinct viewname,viewschema
from syscat.VIEWS
DO
SET SQLTEXT = 'Dynamic Insert into temp table here'
PREPARE s1 FROM SQLTEXT;
EXECUTE s1;
END FOR;
select *
from SESSION.AS_USAGE_RESULTS;
DROP TABLE SESSION.AS_USAGE_RESULTS;
END
Your mistake is that if you wish to return a result-set from session.as_usage_results, then you must declare a cursor for its select, and open that cursor then end the sproc. This is a FAQ. There are examples in the IBM Db2 Server SAMPLES directory and in the Db2 Knowledge Center.
Inside the sproc, you can either use SELECT ... INTO, or use a select within a cursor, or use a SELECT as part of a SET statement.
You should not drop the session table in the procedure in case the result-set won't be consumed before the table gets dropped. Either drop the session table elsewhere or use an alternative design.
In your example you don't need cursor cur1, so below I show a stilted artificial example of what your might mean. It is artificial because you can see that the session table is also redundant for this example, but it shows the use of the cursor for the result-set.
--#SET TERMINATOR #
create or replace procedure dynproc1
language sql
specific dynproc1
dynamic result sets 1
BEGIN
DECLARE v_sqltext varchar(2000);
DECLARE c1 cursor with return to client for s1;
DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS ( viewname varchar(128), viewschema varchar(128) );
insert into session.as_usage_results(viewname, viewschema) select viewname, viewschema from syscat.views;
set v_sqltext = 'select * from session.as_usage_results';
prepare s1 from v_sqltext;
open c1;
END
#

Execute section of SQL based on presense of a linked server

I'm trying to write a query that can run on different servers. One way I'm trying to detect which server i'm on is the presense of a certain linked server (i.e. Server1 will have a link to Server2 and vice versa).
Trouble is, I can't get SQL Server to ignore/skip the code that runs on the non-existant linked server. There are two nearly identical sections of code, one which uses the Linked Server1 and one which does not (because it's running on Server1 already).
drop table #origdates
if exists(select 1 from sys.servers where name = N'Server1')
BEGIN
Select * into #origdates from openquery([Server1],'Select accounts, dates from table1')
END
if not exists(select 1 from sys.servers where name = N'Server1')
BEGIN
Select accounts, dates into #origdates from table1
END
If I execute the individual sections, everything is fine; the code either executes or not as specified, but the moment I run the entire thing together it's as if the server ignores the if exists section, with an error like:
Could not find server 'Server1' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
The reason I'm doing this is so I don't have to maintain two identical scripts with two separate begginning sections.
Using ELSE in place of the second if not exists line results in the server complaining that the #origdates table already exists, even if a drop table command is issued right before the line of the select into command.
Using different table names returns the error to the 'Could not find server' message, despite that it's not even supposed to be executing that code at all...
Try this, SQL is trying to validate the OPENQUERY, but it can't because [Server1] is not a valid linked server. Hiding the OPENQUERY in a variable should fix it.
Note, you need to pass FROM db.owner.table in an OPENQUERY, not just FROM table
declare #sql nvarchar(max)
if object_id('tempdb..#origdates') is not null
drop table #origdates
create table #origdates (accounts int, dates datetime)
if exists(select 1 from sys.servers where name = N'Server1')
BEGIN
set #sql='insert into #origdates Select * from openquery([Server1],''select accounts, dates from db.dbo.table1'')'
exec(#sql)
END
else
BEGIN
insert into #origdates Select accounts, dates from table1
END

SQL Server - How to lock a table until a stored procedure finishes

I want to do this:
create procedure A as
lock table a
-- do some stuff unrelated to a to prepare to update a
-- update a
unlock table a
return table b
Is something like that possible?
Ultimately I want my SQL server reporting services report to call procedure A, and then only show table a after the procedure has finished. (I'm not able to change procedure A to return table a).
Needed this answer myself and from the link provided by David Moye, decided on this and thought it might be of use to others with the same question:
CREATE PROCEDURE ...
AS
BEGIN
BEGIN TRANSACTION
-- lock table "a" till end of transaction
SELECT ...
FROM a
WITH (TABLOCK, HOLDLOCK)
WHERE ...
-- do some other stuff (including inserting/updating table "a")
-- release lock
COMMIT TRANSACTION
END
BEGIN TRANSACTION
select top 1 *
from table1
with (tablock, holdlock)
-- You do lots of things here
COMMIT
This will hold the 'table lock' until the end of your current "transaction".
Use the TABLOCKX lock hint for your transaction. See this article for more information on locking.