What does DELIMITER // do in a Trigger? - sql

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.

Related

What is the purpose of the #SET TERMINATOR statement

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.

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.

In SQL Server, when should you use GO and when should you use semi-colon ;?

I’ve always been confused with when I should use the GO keyword after commands and whether a semi-colon is required at the end of commands. What is the differences and why/when I should use them?
When I run the Generate-script in SQL Server Management Studio, it seems to use GO all over the place, but not the semi-colon.
GO only relates to SSMS - it isn't actual Transact SQL, it just tells SSMS to send the SQL statements between each GO in individual batches sequentially.
The ; is a SQL statement delimiter, but for the most part the engine can interpret where your statements are broken up.
The main exception, and place where the ; is used most often is before a Common Table Expression Statement.
The reason why you see so many GO's in Generated DDL scripts is because of the following rule about batches.
CREATE DEFAULT, CREATE FUNCTION,
CREATE PROCEDURE, CREATE RULE, CREATE
TRIGGER, and CREATE VIEW statements
cannot be combined with other
statements in a batch. The CREATE
statement must begin the batch. All
other statements that follow in that
batch will be interpreted as part of
the definition of the first CREATE
statement.
One of the use cases for Generated DDL is to generate multiple objects in a single file. Because of this a DDL generator must be able to generate batches. As others have said the GO statement ends the batch.
GO
Go is a batch separator. This means that everything in that batch is local to that particular batch.
Any declarations of Variables, Table Variables, etc do not go across GO statements.
#Temp tables are local to a connection, so they span across GO statements.
Semicolon
A Semicolon is a statement terminator. This is purely used to identify that a particular statement has ended.
In most cases, the statement syntax itself is enough to determine the end of a statement.
CTE's however, demand that the WITH is the first statement so you need a semicolon before the WITH.
You should use a semi-colon to terminate every SQL statement. This is defined in the SQL Standards,
Sure, more often than not SQL Server allows you to omit the statement terminator but why get into bad habits?
As others have pointed out, the statement preceding a common table expression (CTE) must be terminated with a semi-colon. As a consequence, from folk who have not fully embraced the semi-colon terminator, we see this:
;WITH ...
which I think looks really odd. I suppose it makes sense in an online forum when you can't tell the quality of code it will be pasted into.
Additionally, a MERGE statement must be terminated by a semi-colon. Do you see a pattern here? These are a couple of the newer additions to TSQL which closely follow SQL Standards. Looks like the SQL Server team are going down the road of mandating the use of the semi-colon terminator.
GO is a batch terminator, a semi-colon is a statement terminator.
you will use GO when you want to have multiple create proc statements in 1 script because create proc has to be the first statement in a batch. If you use common table expressions then the statement before it needs to be terminated with a semi-colon

MySQL DELIMITER syntax errors

This MySQL script installs multiple triggers.
It works on one machine running MySQL 5.0.51b-community. On another machine running MySQL 14.12 Distrib 5.0.45, for redhat-linux-gnu (i386) it fails, with this error message, which seems to be related to the DELIMITER // ... // DELIMITER; syntax :
ERROR 1064 (42000) at line 272: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER; DROP TRIGGER IF EXISTS trigger_name; DELIMITER' at line 1
The script syntax (summarised) is:
DROP TRIGGER IF EXISTS trigger_name;
DELIMITER //
CREATE TRIGGER trigger_name BEFORE UPDATE ON table
FOR EACH ROW BEGIN
-- Trigger logic goes here
END //
DELIMITER;
-- More trigger drop/create statements follow
What is wrong with the script, and how can I correct it?
Try
DELIMITER ;
not
DELIMITER;
You're actually specifying ; as an argument to the DELIMITER command, so not having the space there may be confusing it.
You need a space between 'DELIMITER' and ';'
DELIMITER ;
# not:
DELIMITER;
Just as an add-on, for someone else:
The delimiter is required to enable the entire definition to be passed to the server as a single statement.
Try the below.
I am sure it should solve the purpose.
DELIMITER +
CREATE TRIGGER STUDENT_INSERT_TRIGGER BEFORE INSERT ON FSL_CONNECTIONS
FOR EACH ROW BEGIN
INSERT INTO STUDENT_AUDIT
SET STUDENT_ID = NEW.STUDENT_ID,
MAC_ADDRESS = NEW.MAC_ADDRESS,
IPADDRESS = NEW.IPADDRESS,
EMAIL_ID = NEW.EMAIL_ID ,
START_TIME=NEW.START_TIME,
END_TIME=NEW.END_TIME,
STATUS=NEW.STATUS;
END; +
From the above when we use a DELIMITER. It should be in the form of
DELIMITER +
--
BLOCK OF SQL WHATEVER YOU WANT TO MENTION
--
+
In the version of MySql I use the same error occurs when using the delimiter command, but this version handles the delimiter ";" for statements and delimiter "|" for stored procedures and functions, which i think solves the problem; try this:
DROP TRIGGER IF EXISTS trigger_name;
CREATE TRIGGER trigger_name BEFORE UPDATE ON table
FOR EACH ROW BEGIN
-- Trigger logic goes here
END |
-- other statements or functions here
Hmm I'm having similar problems. I do a mysqldump from Debian Lenny running 5.0.51 and try importing to OpenSolaris running 5.0 and get the same error. And I have DELIMITER ;
Version conflict?