What is the purpose of the #SET TERMINATOR statement - sql

Specifically for SQL stored procedures. Am I supposed to include it at the beginning of every stored procedure such as
--#SET TERMINATOR #
CREATE PROCEDURE Name
LANGUAGE SQL
BEGIN
SELECT * FROM Table
END
#

It's not a statement, it's a directive to change the statement terminator.
You must use another statement terminator different from the default one (;), if a statement you want to run contains a compound statement (with BEGIN ... END) containing other "simple" statements delimited by ;. The statement delimiter inside a compound statement can't be changed, so you have to help the DB2 Command Line Processor to understand, where your whole "complex" statement ends.
BTW, your statement contains a number of mistakes. Each statement (including the last one) inside the BEGIN ... END block must be separated by ;, and you can't "SELECT to nowhere" in a routine.

Related

Problem trying to execute a while loop with insert in db2

I am trying to insert entries into a table:
CREATE TABLE MYTABLE (ID INT);
BEGIN
DECLARE CNT INT DEFAULT 0;
WHILE CNT<100 DO
INSERT INTO MYTABLE(ID) VALUES(CNT);
SET CNT = CNT + 1;
END WHILE;
END
What's wrong with the loop? It won't run. The error it shows is:
Error : an unexpected token "End of starement" was found following "re cnt int default 0". Expected tokens may include "psm_semicolon>" sqlcode=-104 sqlstate=42601, driver=3.67.27
Error occured in:
BEGIN
DECLARE CNT INT DEFAULT 0
This is a frequently asked question, you could have found it with search.
You need to tell whatever tool you use to submit the SQL statement that there is an alternative statement terminator (also known as statement separator), and then use that alternative statement terminator at the end of the SQL block , and any standalone non-compound statements.
Many people use # to indicate the end of the block, different tools often suggest different characters.
For squirrel sql, some versions have a "Statement Separator" property on the SQL tab of 'New Session Properties' which you can set to #, and this is effective the next time you open the session. Your code would then have # at the end of the create table statement, plus # once after the end of the block (in the case that you have two statements, one of which is a compound block). If you have more than two statements each compound-block needs its own # terminator at end of block, and each standalone statement (non compound) needs its own #.
The background is that when you have a compound (multi-statement) SQL block in Db2, the semi-colon is the terminator for statements inside the block, but you need a different terminator to indicate the end of the whole block. Without that terminator, you will get an SQL exception.
Different tools have different ways to specify the alternative statement terminator.
Your question does not mention the tool you use to submit the SQL, or your Db2-server platform, which can be relevant sometimes.
If you submit the SQL using the Db2 command-line-processor (at the shell command line on Windows, Linux/Unix), then you can specify the alternative statement terminator either on the db2 command line ( -td#) , or on the fly inside the file (as long as that file is submitted by the db2 CLP) that contains the SQL statements by having a line that reads --#SET TERMINATOR # . You can use this as often as you like inside a file sent to the CLP, each with a different terminator if necessary and if impacts only the subsequent statements after that line until the next terminator is specified. This method is not usually applicable to java based tools such as squirrel sql, so use the statement separator property for that.

Sequence and Trigger, PL/SQL

I'm using Oracle for the first time, much more used to sql server and their identitys. But now I'm trying to use a sequence and trigger. But keep getting this error I can't fix.
identifiers may not start with any ASCII character other than
letters and numbers. $#_ are also allowed after the first
character. Identifiers enclosed by doublequotes may contain
any character other than a doublequote. Alternative quotes
(q'#...#') cannot use spaces, tabs, or carriage returns as
delimiters. For all other contexts, consult the SQL Language
Reference Manual.
Can anyone help fix it, here is my code.
EXECUTE IMMEDIATE' CREATE SEQUENCE stagechardata_stagecharid
START WITH 1
INCREMENT BY 1;';
EXECUTE IMMEDIATE' CREATE OR REPLACE TRIGGER stagechardata_stagecharid_TRG
BEFORE INSERT
ON stage_char_data
FOR EACH ROW
BEGIN
IF NEW.stage_char_id IS NULL THEN
SELECT stagechardata_stagecharid.NEXTVAL INTO NEW.stage_char_id
FROM DUAL;
END IF;
END;';
Long shot, but looks like you're missing a space after IMMEDIATE and before the quote that starts the statement.
A sequence is an object which contains SQL satements, but doesn't store data.
Triggers are SQL blocks that execute when a manipulation occurs on a table.
First of all, there is no visible reason to use EXECUTE IMMEDIATE. Is there any invisible? It looks like you should just remove it and execute these statements directly in the SQL mode.
Next, it looks like you forgot to use colon: NEW.stage_char_id IS NULL should be :NEW.stage_char_id IS NULL and so on.

Compound Statement unable to change the delimiter

I am attempting to run a simple compound statement within the Query Editor of DB Solo 4.2.2
It appears I am unable to properly change the end of line delimiter. I am using DB2. Here is a simple example that gives the error:
--#SET TERMINATOR #
BEGIN ATOMIC
DECLARE id INT;
SET id = 10;
END #
--#SET TERMINATOR ;
Error is:
An unexpected token "INT" was found following "N ATOMIC DECLARE id". Expected tokens may include: "END-OF-STATEMENT"
Thanks in advance
DB2 only allows the semicolon to be used as a delimiter in Compound SQL. The syntax you are using appears to only be valid when using the db2batch utility (which comes with DB2 Linux/Unix/Windows).
Here is some relevant information from the Information Center (this is from the z/OS IC):
How to code multiple statements in an SQL procedure
Use a semicolon
character to separate SQL statements within an SQL procedure.
The procedure body has no terminating character. Therefore, if the
procedure contains only one statement, you do not need to put a
semicolon after that statement. If the procedure consists of a set of
nested statements, you do not need to put a semicolon after the
outermost statement.

What does DELIMITER // do in a Trigger?

DELIMITER //
What is the of use of it?
It changes the statement delimiter from ; to //. This is so you can write ; in your trigger definition without the MySQL client misinterpreting that as meaning you're done with it.
Note that when changing back, it's DELIMITER ;, not DELIMITER; as I've seen people try to do.
In SQL you close each statement with a delimiter, which is by default a semicolon (;). In a trigger you need to write multiple statements, each ending in a semicolon. To tell MySQL that those semicolons are not the end of your trigger statement, you temporarily change the delimiter from ; to //, so MySQL will know that the trigger statement only ends when it econunters a //.
Add an example:
When working with mysql shell command, we used ; delimiter to close each statement. However, in case, we want to build the store procedures and triggers, we need to add the semicolon ; in these statements also.
delimiter //
create trigger log_students after insert on students
for each row
begin
insert into log_students(change_by, change_at) values(USER(), NOW());
end//
delimiter ;
Simple sets the end of statement delimiter (; semi-colon in standard, default SQL).
Changing the character could be useful if you want to use ; in your SQL, or you are using embedded SQL (where it might lead to confusion). similarly the // in your example could lead to confusion in embedded SQL, or you might want to use it in your SQL. So imply use DELIMITER to set the delimiter that is appropriate for your application and needs.
Read the (ummmm) mysql documentation.
delimiter is the marker for the end of each command you send to the mysql command line client.
delimiter is not only related to triggers, but defining triggers and stored procedures is one strong use case as you wish them to contain semicolons (;) which are otherwise the default delimiter.

What is the difference between ";" and "GO" in T-SQL?

I use ADO.NET as well as the sqlcmd utility to send SQL scripts to SQL Server 2008. What is the difference between using ; and GO to separate chunks of SQL?
GO is not actually a T-SQL command. The GO command was introduced by Microsoft tools as a way to separate batch statements such as the end of a stored procedure. GO is supported by the Microsoft SQL stack tools but is not formally part of other tools.
You cannot put a GO into a string of SQL and send it as part of a ADO.NET command object as SQL itself does not understand the term. Another way to demonstrate this is with the profiler: set up some statements that use GO in Query Analyzer/Management Studio and then run the profiler when you execute. You will see they are issued as separate commands to the server.
The semi-colon is used to signify the end of a statement itself, not necessarily a whole batch.
http://msdn.microsoft.com/en-us/library/ms188037.aspx
"GO" is similar to ; in many cases, but does in fact signify the end of a batch.
Each batch is committed when the "GO" statement is called, so if you have:
SELECT * FROM table-that-does-not-exist;
SELECT * FROM good-table;
in your batch, then the good-table select will never get called because the first select will cause an error.
If you instead had:
SELECT * FROM table-that-does-not-exist
GO
SELECT * FROM good-table
GO
The first select statement still causes an error, but since the second statement is in its own batch, it will still execute.
GO has nothing to do with committing a transaction.
semicolon is a statement separator. The previous statement(s) is not necessarily executed when a semicolon is encountered.
GO
Signifies the end of a batch. Executes the previous batch of statements, as does encountering the end of the block.
GO 2
Means execute the batch that many times. I think I've used that option maybe twice in my life. Then again, I'm not a DBA by trade.
Under SQL Server TSQL (2005 - 2016) bear in mind that:
Semicolon (;) is a block terminator.
GO is a batch terminator.
Additionally, GO can be used to invoke the same DML block multiple times using the following syntax:
GO [count]
Where [count] is a positive integer that indicates how many times the TSQL block of commands preceding said GO are to be carried out over and over.
Also, unlike semicolon, GO is mandatory before a new DDL, say, when you create a new view, since a semicolon separating previous commands will trigger an error. For example:
drop view #temporary_viewGO
create view #another_view...
--> NO ERRORS
If you replaced GO with a semicolon in the previous example, it will raise the following error message:
'CREATE VIEW' must be the first statement in a query batch.
'GO' is typically used to indicate the end of a batch of SQL statements which means that you could have a begin transaction and end transaction wrapped up into a single collection of statements that could fail or succeed together.
';' is generally used to separate multiple SQL statements from one another. This is noticable in SQL scripts that need to return multiple recordsets, such as `select * from table1; select * from table2;' which would result in two separate recordsets on the client's side.
The command GO means the end of a batch.
Therefore all variables declared before GO are invalid after the GO command.
Against the semicolon does not end the batch.
If You will use a DML command in a procedure, use the semicolon instead GO.
For example:
CREATE PROCEDURE SpMyProc
#myProcParam VARCHAR(20)
AS
DECLARE #myOtherParam INT = 5
;DISABLE TRIGGER ALL ON tMyTable
UPDATE tMyTable SET myVar = #myProcParam, mySecondVar = #myOtherParam
;ENABLE TRIGGER OLL ON tMyTable
I thought the ; character separates a list of SQL commands, GO just instructs SQL Server to commit all the previous commands.