I have SQL Server data in the following format :
DECLARE #tblData TABLE
(
ID int,
texttofind varchar(2000),
txttoReplace varchar(2000),
Body varchar(max)
)
INSERT INTO #tblData
VALUES (1,'url1','someurl1','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>')
INSERT INTO #tblData
VALUES (1,'url2','someurl2','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>')
INSERT INTO #tblData
VALUES (1,'url3','someurl3','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>')
INSERT INTO #tblData
VALUES (2,'url1','someotherurl1','<href="url1">test</a><href="url2">test2</a>')
INSERT INTO #tblData
VALUES (2,'url2','someotherurl2','<href="url2">test</a><href="url2">test2</a>')
SELECT * FROM #tblData
DECLARE #tblExpectedData TABLE (ID int,
texttofind varchar(2000),
txttoReplace varchar(2000),
Body varchar(max),
BodyAfterChange varchar(max)
)
INSERT INTO #tblExpectedData
VALUES (1,'url1','someurl1','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>','<href="someurl1">test</a><href="someurl2">test2</a><href="someurl3">test3</a>')
INSERT INTO #tblExpectedData
VALUES (1,'url2','someurl2','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>','<href="someurl1">test</a><href="someurl2">test2</a><href="someurl3">test3</a>')
INSERT INTO #tblExpectedData
VALUES (1,'url3','someurl3','<href="url1">test</a><href="url2">test2</a><href="url3">test3</a>','<href="someurl1">test</a><href="someurl2">test2</a><href="someurl3">test3</a>')
INSERT INTO #tblExpectedData
VALUES (2,'url1','someotherurl1','<href="url1">test</a><href="url2">test2</a>','<href="someotherurl1">test</a><href="someotherurl2">test2</a>')
INSERT INTO #tblExpectedData
VALUES (2,'url2','someotherurl2','<href="url2">test</a><href="url2">test2</a>','<href="someotherurl1">test</a><href="someotherurl2">test2</a>')
SELECT * FROM #tblExpectedData
First table is how the data looks like and second table is how I want the expected result, essentially its doing a find and replace from "texttofind" to "Body" using the "txttoReplace" column but I am unable to figure out how to do it for EACH ID and for each row so that every row for a particular ID has the same "BodyAfterChange "
Related
I'm trying to create TRIGGERS in MySQL but I got a syntax error message. Here's my code for creating the tables and inserting the values:
The first table:
CREATE TABLE widgetSale (
id INTEGER auto_increment,
item_id INT,
customer_id INT,
quan INT,
price INT,
reconciled INT,
primary key (id));
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (1, 3, 5, 1995, 0);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (2, 2, 3, 1495, 1);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (3, 1, 1, 2995, 0);
SELECT * FROM widgetSale;
My first trigger for the first table:
delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale for each row
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//
And here are my tables to create trigger for timestamps:
DROP TABLE IF EXISTS widgetSale;
CREATE TABLE widgetCustomer(
id integer auto_increment,
name TEXT,
last_order_id INT,
stamp TEXT,
primary key(id) );
CREATE TABLE widgetSale (
id integer auto_increment,
item_id INT,
customer_id INTEGER,
quan INT,
price INT,
stamp TEXT,
primary key(id) );
CREATE TABLE widgetLog (
id integer auto_increment,
stamp TEXT,
event TEXT,
username TEXT,
tablename TEXT,
table_id INT,
primary key(id));
INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');
SELECT * FROM widgetCustomer;
delimiter //
CREATE TRIGGER stampSale before insert on widgetSale for each row
BEGIN
SET NEW.stamp = CURDATE();
update widgetCustomer set last_order_id = new.item_id where widgetCustomer.id = new.customer_id;
update widgetCustomer set stamp = new.stamp;
INSERT INTO widgetLog (stamp, event, username, tablename, table_id) VALUES (NEW.stamp, 'INSERT ', 'TRIGGER', 'widgetSale', NEW.customer_id);
END
//
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 1995);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 1495);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 2995);
SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;
SELECT * FROM widgetLog;
So my problem is:
I could not create the first trigger because it seems the raise function does not exist in MySQL. I was advised to use Signal statement but I don't know what syntax should I put?
I was able to create the trigger for timestamps but I got error code 1442. I don't know what went wrong with my syntax?
*Updated: I was able to solve my problems now, for the second trigger, turns out I need to CREATE TRIGGER BEFORE INSERT, not AFTER INSERT (because otherwise I cannot update the table), and wrote two UPDATE statements to update the widgetCustomer table in which I want to update the id and the stamp column, and I have to do that by writing two separate UPDATE statements.
Summary of errors from above comment thread:
You need to use DELIMITER when defining stored routines in the MySQL client. See https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
Use the SIGNAL statement to raise errors in a MySQL stored routine. See https://dev.mysql.com/doc/refman/8.0/en/signal.html
Your condition appears to be reconciled = 1, and you reference that column in the row that spawned the trigger as NEW.reconciled. You don't need to SELECT from the table to get that column.
delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//
User blabla_bingo noticed you had mistakenly referenced reconciled in some INSERT statements where it didn't belong. I guess it was the result of copy & paste of some lines of code.
Re error 1442: MySQL does not allow you to INSERT/UPDATE/DELETE the same table for which the trigger was spawned. In other words, if the trigger is for an operation ON widgetSale, then you can't UPDATE widgetSale in that trigger.
But you don't need to UPDATE the table to change one column in current row for which the trigger spawned. You simply reference the columns of current row with NEW.columnName like the following to set one column to a scalar value:
SET NEW.stamp = CURDATE();
CURDATE() is an equivalent way of writing DATE(NOW()).
for example:
CREATE TABLE test_serial_no_entity (
id BIGINT,
serial_no BIGINT NOT NULL UNIQUE,
PRIMARY KEY (id)
);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (1,1);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (2,2);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (3,3);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (4,4);
serial_no is a unique column, when i execute the sql: update test_serial_no_entity set serial_no=serial_no+1 where id>=1 ,
I got the error Error Code: 1062. Duplicate entry '2' for key 'serial_no' 0.034 sec in mysql, Is there any other way to solve this problem except to cancel the unique constraint?
Yes, update the higher values first.
update test_serial_no_entity
set serial_no=serial_no+1
where id>=1
ORDER BY serial_no DESC
An example of this can also be found in the manual.
Try loop to update one record at a time. Start from the maximum number.
CREATE TABLE test_serial_no_entity (
id BIGINT,
serial_no BIGINT NOT NULL UNIQUE,
PRIMARY KEY (id)
);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (1,1);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (2,2);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (3,3);
INSERT INTO test_serial_no_entity (id, serial_no) VALUES (4,4);
Declare #Min int, #Iterator int
Select #Min = min(serial_no) from test_serial_no_entity
Select #Iterator = max(serial_no) from test_serial_no_entity
While(#Iterator >= #Min)
BEGIN
Update test_serial_no_entity
Set serial_no = serial_no + 1
Where serial_no = #Iterator
#Iterator = #Iterator - 1
END
Trying to execute 3 insert commands in MySQL temporary Table in Stored Procedure but select command shows only first insert was executed/inserted.
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
#Fist Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values('2017-04-15', 400);
#Second Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtHalf, #TotalOTMinutesHalf);
#Third Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtFull, #TotalOTMinutesFull);
Select command returns only 2017-04-15, 400 while values from variables in 2nd and 3rd insert are not listed. If I remove the first insert command, the second one gets inserted and not the third one.
EDIT 2 :
Providing complete stored procedure
CREATE DEFINER=`root`#`localhost` PROCEDURE `Test0`()
begin
select #DateOtHalf:=DateofIn, #TotalOTMinutesHalf:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkHalfDayInMin and TotalOTMinutes < #ExtraWorkFullDayInMin and EmpID = P_EmpID;
select #DateOtFull:=DateofIn, #TotalOTMinutesFull:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkFullDayInMin and EmpID = P_EmpID;
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
#Fist Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values('2017-04-15', 400);
#Second Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtHalf, #TotalOTMinutesHalf);
#Third Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtFull, #TotalOTMinutesFull);
select * from OtDates;
end
EDIT 3 : Providing Sample Data and Table Structure from "hrtpunch"
Create Statement
CREATE TABLE `hrtpunch` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`TotalOTMinutes` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=464 DEFAULT CHARSET=utf8;
Sample Data Insert
insert into hrtpunch (TotalOTMinutes) values(61);
insert into hrtpunch (TotalOTMinutes) values(600);
insert into hrtpunch (TotalOTMinutes) values(301);
insert into hrtpunch (TotalOTMinutes) values(0);
And Int Values returned for ExtraWorkHalfDayInMin is 160 and ExtraWorkFullDayInMin is 240
Try it like this:
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
INSERT INTO OtDates (OtDatesList,TotalOTMinutes) VALUES
('2017-04-15', 400), (#DateOtHalf, #TotalOTMinutesHalf), (#DateOtHalf, #TotalOTMinutesHalf)
EDIT:
For SQL 2005, the code above doesn't work, so try this:
INSERT INTO OtDates (OtDatesList,TotalOTMinutes)
SELECT '2017-04-15', 400
UNION ALL
SELECT #DateOtHalf, #TotalOTMinutesHalf
UNION ALL
SELECT #DateOtHalf, #TotalOTMinutesHalf
Solved!
DROP TEMPORARY TABLE IF EXISTS `OtDates`;
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
insert into OtDates(OtDatesList,TotalOTMinutes) select #DateOtHalf:=DateofIn, #TotalOTMinutesHalf:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkHalfDayInMin and TotalOTMinutes < #ExtraWorkFullDayInMin and EmpID = P_EmpID;
insert into OtDates(OtDatesList,TotalOTMinutes) select #DateOtFull:=DateofIn, #TotalOTMinutesFull:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkFullDayInMin and EmpID = P_EmpID;
I'm trying to use "MERGE" in two temporary tables, I failed to get results.
Error: Incorrect syntax near the keyword 'AS'.
Create Table #tmp1
(
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
)
Create Table #tmp2
(
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
)
insert into #tmp1 values ('BE01','2012-08-01 00:00:00',1,100)
insert into #tmp1 values ('BE02','2012-08-01 00:00:00',2,100)
insert into #tmp1 values ('BE03','2012-08-01 00:00:00',3,100)
insert into #tmp1 values ('BE04','2012-08-01 00:00:00',4,100)
insert into #tmp1 values ('BE05','2012-08-01 00:00:00',5,100)
insert into #tmp2 values ('BE01','2012-08-01 00:00:00',1,100)
insert into #tmp2 values ('BE02','2012-08-01 00:00:00',2,200)
insert into #tmp2 values ('BE03','2012-08-01 00:00:00',3,300)
insert into #tmp2 values ('BE04','2012-08-01 01:00:00',4,400)
insert into #tmp2 values ('BE05','2012-08-01 02:00:00',5,500)
MERGE #tmp1 AS [Target]
USING #tmp2 AS [Source]
ON ([Target].[Server] = [Source].[Server]
AND [Target].[DateTime] = [Source].[DateTime]
AND [Target].[IdComponent] = [Source].[IdComponent])
WHEN MATCHED THEN
UPDATE
SET [Target].AvgTimeTaken = [Source].AvgTimeTaken
WHEN NOT MATCHED THEN
INSERT ([Target].[Server], [Target].[DateTime], [Target].IdComponent, [Target].AvgTimeTaken)
VALUES ([Source].[Server], [Source].[DateTime], [Source].IdComponent, [Source].AvgTimeTaken);
I'm not sure I can be wrong. At the end also has a semicolon.
Help please!
I've run into this error before and it was because SQL Server 2008 R2 does not support the merge syntax unless you set the compatibility mode by executing the following:
ALTER DATABASE mydatabase SET COMPATIBILITY_LEVEL = 100
Where mydatabase is the name of the database you want to apply this to.
Take out the Target aliases in the INSERT clause.
Create Table #tmp1 (
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
);
Create Table #tmp2 (
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
);
insert into #tmp1 values ('BE01','2012-08-01 00:00:00',1,100);
insert into #tmp1 values ('BE02','2012-08-01 00:00:00',2,100);
insert into #tmp1 values ('BE03','2012-08-01 00:00:00',3,100);
insert into #tmp1 values ('BE04','2012-08-01 00:00:00',4,100);
insert into #tmp1 values ('BE05','2012-08-01 00:00:00',5,100);
insert into #tmp2 values ('BE01','2012-08-01 00:00:00',1,100);
insert into #tmp2 values ('BE02','2012-08-01 00:00:00',2,200);
insert into #tmp2 values ('BE03','2012-08-01 00:00:00',3,300);
insert into #tmp2 values ('BE04','2012-08-01 01:00:00',4,400);
insert into #tmp2 values ('BE05','2012-08-01 02:00:00',5,500);
MERGE #tmp1 AS Target
USING #tmp2 AS Source
ON (Target.Server = Source.Server
AND Target.DateTime = Source.DateTime
AND Target.IdComponent = Source.IdComponent)
WHEN MATCHED THEN
UPDATE
SET Target.AvgTimeTaken = Source.AvgTimeTaken
WHEN NOT MATCHED THEN
INSERT (Server, DateTime, IdComponent, AvgTimeTaken)
VALUES (Source.Server, Source.DateTime, Source.IdComponent, Source.AvgTimeTaken);
The insert column list used in the MERGE statement cannot contain multi-part identifiers. Use single part identifiers instead.
DROP PROCEDURE IF EXISTS CreateTopic;
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
INSERT INTO forum_topics (forum_id, user_id, title, language)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET #tid := LAST_INSERT_ID();
INSERT INTO forum_posts (topic_id, user_id, subject, content) VALUES (#tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (obj_id, user_id, type, action) VALUES (#tid, i_user_id, 'Topics', 'Topic Created');
END;
I'm not sure what's wrong with it. MySQL tells me all sorts of things are incorrect, it just doesn't want to be created. Also, the parameters are identical types and lengths to their respective tables.
It is your first ";" that breaks procedure definition and mysql thinks you are done and treats whatever goes after ";" as another query.
You have to use delimiter for stored procedures.
DELIMITER $$
DROP PROCEDURE IF EXISTS CreateTopic$$
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
INSERT INTO forum_topics (forum_id, user_id, title, language)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET #tid := LAST_INSERT_ID();
INSERT INTO forum_posts (topic_id, user_id, subject, content) VALUES (#tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (obj_id, user_id, type, action) VALUES (#tid, i_user_id, 'Topics', 'Topic Created');
END
$$
DELIMITER ;
There are a few problems. I hope I got them all:
DROP PROCEDURE IF EXISTS CreateTopic;
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
DECLARE tid INT;
INSERT INTO forum_topics (`forum_id`, `user_id`, `title`, `language`)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET tid = LAST_INSERT_ID();
INSERT INTO forum_posts (`topic_id`, `user_id`, `subject`, `content`) VALUES (tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (`obj_id`, `user_id`, `type`, `action`) VALUES (tid, i_user_id, 'Topics', 'Topic Created');
END;