I'm trying to write a stored procedure which takes in a value then compares it with a table value. For example
The procedure takes in a varchar(30) value say " RED " as c_title then compares it with all the titles in a table called campaign, if matching then update some column with a certain value.
basically how would you compare two variables of string values in mysql?
I've tried different comparison methods using LIKE, IN and =
CREATE PROCEDURE sp_finish_campaign(in c_title varchar(30))
Begin
Update campaign
Set TITLE = "Hello"
where TITLE = c_title;
END
New Title value should be hello where TITLE matches the input value
but im getting error code 1064 for syntax error.
Appreciate any feedback. Thank you
You need to end your update with a semicolon, but first redefine the delimiter which will be used by the stored procedure:
DELIMITER // ;
CREATE PROCEDURE sp_finish_campaign(IN c_title varchar(30))
BEGIN
UPDATE campaign
SET TITLE = 'Hello'
WHERE TITLE = c_title;
END //
Also, you should try to use single quotes when defining string literals in MySQL. Double quotes most likely would work also, but they are mainly used to indicate database objects (e.g. database, table, and column names), rather than strings.
Related
I have a mysql table of employees with columns surname and workhours for each employee . I am trying to create a stored function that takes a letter as input and returns the sum of workhours of all employees whose surname starts from the input letter .This is basically an easy task but I am a complete beginner in sql and I need your help .
What I tried :
CREATE FUNCTION sumOfTotalSickHours(letter CHAR(1))
RETURNS DOUBLE DETERMINISTIC
BEGIN
DECLARE total DOUBLE DEFAULT 0
SELECT SUM(sickleavehours) INTO total
FROM employee where lastName LIKE '#letter%'
RETURN total
END
With my above code I get a syntax error since I do not know how to write the query correctly .
First of all, each statement needs to end with a semicolon (;).
Be sure you read https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html to understand how to use DELIMITER when defining stored programs.
Also to reference an input variable, don't put inside quotes.
And don't use #letter because variables with the # sigil are not the same variable as without the sigil.
So for example:
CREATE FUNCTION sumOfTotalSickHours(letter CHAR(1))
RETURNS DOUBLE DETERMINISTIC
BEGIN
DECLARE total DOUBLE DEFAULT 0;
SELECT SUM(sickleavehours) INTO total
FROM employee where lastName LIKE CONCAT(letter, '%');
RETURN total;
END
I have a mysql table of employees with columns surname and workhours for each employee . I am trying to create a stored function that takes a letter as input and returns the sum of workhours of all employees whose surname starts from the input letter .This is basically an easy task but I am a complete beginner in sql and I need your help .
What I tried :
CREATE FUNCTION sumOfTotalSickHours(letter CHAR(1))
RETURNS DOUBLE DETERMINISTIC
BEGIN
DECLARE total DOUBLE DEFAULT 0
SELECT SUM(sickleavehours) INTO total
FROM employee where lastName LIKE '#letter%'
RETURN total
END
With my above code I get a syntax error since I do not know how to write the query correctly .
First of all, each statement needs to end with a semicolon (;).
Be sure you read https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html to understand how to use DELIMITER when defining stored programs.
Also to reference an input variable, don't put inside quotes.
And don't use #letter because variables with the # sigil are not the same variable as without the sigil.
So for example:
CREATE FUNCTION sumOfTotalSickHours(letter CHAR(1))
RETURNS DOUBLE DETERMINISTIC
BEGIN
DECLARE total DOUBLE DEFAULT 0;
SELECT SUM(sickleavehours) INTO total
FROM employee where lastName LIKE CONCAT(letter, '%');
RETURN total;
END
I have created one procedure which take 2 parameter and it check the count.
But when I pass "" blank value It still return 1 count.
Did not get it why it is working like this.
Thanks for the help below is my procedure
DELIMITER $$
CREATE DEFINER=`dadclient`#`123.63.249.169` PROCEDURE `checkInOut`(IN grid varchar(50),OUT count INT)
begin
select count(GRIDID) into count from GRIDID where GRIDID=grid;
select count;
END
when I call
checkInOut("",#aaa);
select #aaa;
When I call this,it return me 1 which is wrong.
But when I pass "" blank value It still return 1 count.
Because when you say it is blank by providing an empty string it is a value. Empty string is also treated as a value in database and hence you get count as 1
The MySQL docs says:
COUNT(expr)
Returns a count of the number of non-NULL values of expr in the rows
retrieved by a SELECT statement. The result is a BIGINT value.
So if you want the count to return 0 then instead of making the string as empty "" you need to make the value as NULL.
Yo mate, try this:
DELIMITER $$
CREATE
DEFINER=`dadclient`#`123.63.249.169`
PROCEDURE `checkInOut`(
IN `grid` VARCHAR(50),
OUT `count` INT
)
BEGIN
-- insert value into variable
SET `count` = (
select count(GRIDID)
from GRIDID
where GRIDID=grid;
);
END$$
DELIMITER ;
So in your application, e.g. php you can CALL checkInOut($input, $output);. No need for the final SELECT... part in your initial code, afaik, because you already declared count as an OUT in the procedure parameter
Note:
Is the name GRIDID the name of your table? because as I see, you also used it in your WHERE statement as a key filter
Regarding your query, supposedly it is expected to contain one row of result. Kindly check that also mate
I am writing a stored procedure in mysql which simply returns the row with ID provided or return all table when no ID is provided.
CREATE DEFINER=`root`#`localhost` PROCEDURE `SLICE_GET`(`slice_id` int)
BEGIN
SELECT *
FROM `thesis_db`.`SLICE_INFO`
WHERE (SLICE_ID = `slice_id` OR `slice_id` IS NULL);
END
I have used the same idea in ms-sql for years yet it doesn't seem to work for mysql since no matter which ID is passed, the procedure returns entire table.
What am I missing here ?
This is a way to write procedures in mysql
DELIMITER $$
CREATE PROCEDURE `name of procedure` (x CHAR(1), D1 DATE, D2 DATE)
BEGIN
SELECT name of columns you want to display
FROM table name
WHERE SLICE_ID= x
OR SLICE_ID IS NULL;
END
$$
Note: Moreover mysql is not case sensitive means all caps or all small will not effect it.
delimiter is used to:
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises.
By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.
It must be simple, but I'm making my first steps into Postgres functions and I can't find anything that works...
I'd like to create a function that will modify a table and / or column and I can't find the right way of specifying my tables and columns as arguments in my function.
Something like:
CREATE OR REPLACE FUNCTION foo(t table)
RETURNS void AS $$
BEGIN
alter table t add column c1 varchar(20);
alter table t add column c2 varchar(20);
alter table t add column c3 varchar(20);
alter table t add column c4 varchar(20);
END;
$$ LANGUAGE PLPGSQL;
select foo(some_table)
In another case, I'd like to have a function that alters a certain column from a certain table:
CREATE OR REPLACE FUNCTION foo(t table, c column)
RETURNS void AS $$
BEGIN
UPDATE t SET c = "This is a test";
END;
$$ LANGUAGE PLPGSQL;
Is it possible to do that?
You must defend against SQL injection whenever you turn user input into code. That includes table and column names coming from system catalogs or from direct user input alike. This way you also prevent trivial exceptions with non-standard identifiers. There are basically three built-in methods:
1. format()
1st query, sanitized:
CREATE OR REPLACE FUNCTION foo(_t text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format('
ALTER TABLE %I ADD COLUMN c1 varchar(20)
, ADD COLUMN c2 varchar(20)', _t);
END
$func$;
format() requires Postgres 9.1 or later. Use it with the %I format specifier.
The table name alone may be ambiguous. You may have to provide the schema name to avoid changing the wrong table by accident. Related:
INSERT with dynamic table name in trigger function
How does the search_path influence identifier resolution and the "current schema"
Aside: adding multiple columns with a single ALTER TABLE command is cheaper.
2. regclass
You can also use a cast to a registered class (regclass) for the special case of existing table names. Optionally schema-qualified. This fails immediately and gracefully for table names that are not be valid and visible to the calling user. The 1st query sanitized with a cast to regclass:
CREATE OR REPLACE FUNCTION foo(_t regclass)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE 'ALTER TABLE ' || _t || ' ADD COLUMN c1 varchar(20)
, ADD COLUMN c2 varchar(20)';
END
$func$;
Call:
SELECT foo('table_name');
Or:
SELECT foo('my_schema.table_name'::regclass);
Aside: consider using just text instead of varchar(20).
3. quote_ident()
The 2nd query sanitized:
CREATE OR REPLACE FUNCTION foo(_t regclass, _c text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE 'UPDATE ' || _t -- sanitized with regclass
|| ' SET ' || quote_ident(_c) || ' = ''This is a test''';
END
$func$;
For multiple concatenations / interpolations, format() is cleaner ...
Related answers:
Table name as a PostgreSQL function parameter
Postgres functions vs prepared queries
Case sensitive!
Be aware that unquoted identifiers are not cast to lower case here. When used as identifier in SQL [Postgres casts to lower case automatically][7]. But here we pass strings for dynamic SQL. When escaped as demonstrated, CaMel-case identifiers (like UserS) will be preserved by doublequoting ("UserS"), just like other non-standard names like "name with space" "SELECT"etc. Hence, names are case sensitive in this context.
My standing advice is to use legal lower case identifiers exclusively and never worry about that.
Aside: single quotes are for values, double quotes are for identifiers. See:
Are PostgreSQL column names case-sensitive?