I am creating a program using C# to read a set of csv files (approx. 30 million), parse through for certain pieces of information, and add these data from the csv files to a set of MySQL database tables that I'm creating. A part of this is causing me some headache...
I have a table called custId_nums with a customer ID and the customer's name. Each customer then also has their own table with a single field subvisitid which represents each time they visited the business (a new row for each visit). Each time I find a customer in a csv file, I want to check if they have already been added to the database by checking for their custId in the custId_nums table. If they have NOT been added to the database, I want to add a new row to the customer database with their custid and name, and I also want to create a new table with subvisitid field.
An example of the query that I have C# generate is below, which would represent two customers.
DELIMITER $$
CREATE PROCEDURE `custs`.`custExists459156`()
BEGIN
DECLARE numRows INT DEFAULT 0;
SELECT COUNT(*) INTO numRows FROM `custs`.`custId_nums` WHERE `custId` = 459156;
SELECT numRows;
IF numRows = 0 THEN
CREATE TABLE `custs`.`459156_visits` (`subvisitid` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `custs`.`custId_nums` (`custId`, `custName`) VALUES ('459156', 'fName lName');
ALTER TABLE `custs`.`459156_visits`
ADD PRIMARY KEY(`subvisitid`);
ELSE
UPDATE `custs`.`custId_nums` SET `custName` = 'fName lName' WHERE `custId_nums`.`custId` = 459156;
END IF;
INSERT INTO `custs`.`459156_visits` (`subvisitid`) VALUES ('34800006');
END$$
CALL `custs`.`custExists459156`()$$
DROP PROCEDURE IF EXISTS `custs`.`custExists459156`$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE `custs`.`custExists539642`()
BEGIN
DECLARE numRows INT DEFAULT 0;
SELECT COUNT(*) INTO numRows FROM `custs`.`custId_nums` WHERE `custId` = 539642;
SELECT numRows;
IF numRows = 0 THEN
CREATE TABLE `custs`.`539642_visits` (`subvisitid` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `custs`.`custId_nums` (`custId`, `custName`) VALUES ('539642', 'fName2 lName2');
ALTER TABLE `custs`.`539642_visits`
ADD PRIMARY KEY(`subvisitid`);
ELSE
UPDATE `custs`.`custId_nums` SET `custName` = 'fName2 lName2' WHERE `custId_nums`.`custId` = 539642;
END IF;
INSERT INTO `custs`.`539642_visits` (`subvisitid`) VALUES ('34800006');
END$$
CALL `custs`.`custExists539642`()$$
DROP PROCEDURE IF EXISTS `custs`.`custExists539642`$$
DELIMITER ;
Presently, I'm outputing the generated queries to a set of .sql files and then manually importing them using the phpmyadmin tool, but I'm getting the error below. I've tried copying the generated SQL and pasting it on the "SQL" page of my phpmyadmin tool. In either case, it will execute correctly if I only repeat the sequence three or four times (three or four new customers), but if I add more than that I get the following from phpmyadmin:
1 errors were found during analysis.
Missing expression. (near "ON" at position 25)
SQL query: Copy Edit Edit
SET FOREIGN_KEY_CHECKS = ON;
MySQL said: Documentation
#2014 - Commands out of sync; you can't run this command now
Any ideas where I'm going wrong?
Related
A simple BEFORE INSERT Stored Procedure fails with 1st row of the dataset including the columns names instead of data :
SET NEW.`COORD` = POINT (NEW.`GPS_Longitude`, NEW.`GPS_Latitude`)
I'm trying to insert a condition to skip the first row :
IF ((`GPS_Longitude` BETWEEN 0 AND 90) AND (`GPS_Latitude` BETWEEN 0 AND 90)) THEN
SET NEW.`COORD` = POINT (NEW.`GPS_Longitude`, NEW.`GPS_Latitude`)
But I can't save it and the error message is not clear.
As per request, some more details below, but I'm using PhpMyAdmin interface, so the code above is what that really counts. Same for the data, it's provided by another software (with the fields names in the first row - that I'd like to skip).
CREATE TABLE `obs` (
`COORD` point DEFAULT NULL,
`GPS_Longitude` decimal(10,7) DEFAULT NULL,
`GPS_Latitude` decimal(9,7) DEFAULT NULL,
)
DELIMITER $$
CREATE TRIGGER `geom` BEFORE INSERT ON `obs` FOR EACH ROW SET NEW.`COORD` = POINT (NEW.`GPS_Longitude`, NEW.`GPS_Latitude`)
$$
DELIMITER ;
What does not work :
importing a .csv through the phpmyadmin interface (even when checking "ignore errors on insert"), with values
'GPS_Longitude', 'GPS_Latitude'
46.1693780, 6.0487320
...
The (latest) trigger that does not work :
CREATE TRIGGER `geom`
BEFORE INSERT
ON `obs`
FOR EACH ROW
SET NEW.`COORD` = CASE WHEN NEW.`GPS_Longitude` BETWEEN 0 AND 90 AND NEW.`GPS_Latitude` BETWEEN 0 AND 90
THEN POINT (NEW.`GPS_Longitude`, NEW.`GPS_Latitude`)
ELSE POINT (0, 0)
END;
Why is the data not being inserted on the table when I execute the procedure, what seems to be lacking with the code?
I'm testing the procedure on phpMyAdmin > myDatabase > Procedures "Routines Tab" and clicking "Execute", prompts with a modal and ask for the values of "#idproc and #nameproc.
I tried with just the INSERT code it works, but when I add the IF condition it doesn't work.
Using XAMPP 8.0.3,
10.4.18-MariaDB
DELIMITER $$
CREATE DEFINER=`root`#`localhost:3307` PROCEDURE `testproc`(IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
IF #idproc = 0 THEN
INSERT INTO testproc(
id,
name)
VALUES(
#idproc,
#nameproc
);
ELSE
UPDATE testproc
SET
id = #idproc,
name = #nameproc
WHERE id = #idproc;
END IF;
SELECT * FROM testproc;
END$$
DELIMITER ;
You mix local variables (their names have not leading #) and user-defined variables (with single leading #). This is two different variable types, with different scopes and datatype rules. Procedure parameters are local variables too.
So when you use UDV which was not used previously you receive NULL as its value - and your code works incorrectly. Use LV everywhere:
CREATE DEFINER=`root`#`localhost:3307`
PROCEDURE `testproc` (IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
IF idproc = 0 THEN
INSERT INTO testproc (name) VALUES (nameproc);
ELSE
UPDATE testproc SET name = nameproc WHERE id = idproc;
END IF;
SELECT * FROM testproc;
END
You do not check does specified idproc value exists in the table. If it is specified (not zero) but not exists then your UPDATE won't update anything. Assuming that id is autoincremented primary key of the table I recommend to use
CREATE DEFINER=`root`#`localhost:3307`
PROCEDURE `testproc` (IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
INSERT INTO testproc (id, name)
VALUES (idproc, nameproc)
ON DUPLICATE KEY
UPDATE name = VALUES(name);
SELECT * FROM testproc;
END
If specified idproc value exists in id column the row will be updated, if not then the new row will be inserted.
Additionally - I recommend you to provide NULL value instead of zero when you want to insert new row with specified nameproc value. NULL always cause autoincremented primary key generation whereas zero needs in specific server option setting.
I have defined the following stored procedure to add/update a table called ImportedProduct.
If the primary key, ImportedProductId is provided and is greater than zero, then update the exiting record otherwise insert a new one:
DELIMITER //
CREATE PROCEDURE AddOrUpdateImportedProduct (
IN ImportedProductId BIGINT,
IN UniqueThirdPartyCode VARCHAR(64),
IN BranchId BIGINT
)
BEGIN
IF ImportedProductId <= 0 THEN
INSERT INTO ImportedProduct(UniqueThirdPartyCode, BranchId)
VALUES(UniqueThirdPartyCode, BranchId);
ELSE
UPDATE
ImportedProduct
SET
UniqueThirdPartyCode = UniqueThirdPartyCode,
BranchId = BranchId
WHERE
ImportedProductId = ImportedProductId;
END IF;
END //
DELIMITER ;
Now I run the following code to update an existing row:
CALL AddOrUpdateImportedProduct (1, 'y-105', 24);
I can see that the record with with ImportedProductId = 1 exists in the table, but I am getting the following error:
You are using safe update mode and you tried to update a table without
a WHERE that uses a KEY column To disable safe mode
I am pretty sure ImportedProductId = ImportedProductId holds always.. Perhaps rename your variable or add an alias to the updated table.
On a Before Insert trigger I want to calculate the value
of a column based on two colums in the inserted record
and values of columns in other tables linked to the table being updated
Testing this I just created the code to access one of the
filelds in another table up the chain. But when executing I
had an error
CREATE DEFINER = CURRENT_USER TRIGGER `infrastructure`.`Wall_Drop_BEFORE_INSERT` BEFORE INSERT ON `Wall_Drop` FOR EACH ROW
BEGIN
Declare wall_temp decimal(6,2) default null;
Declare room_temp decimal (8,2) default null;
select r.dist_wire_closet into room_temp from rooms as r
where r.Residence_residence_id = new.Wall_rooms_Residence_residence_id
and r.Residence_residence_id = new.Wall_rooms_Residence_residence_id;
END
Error message when inserting record
My mistake, 2nd line was the same as the first. I need
select r.dist_wire_closet into room_temp from rooms as r
where r.Residence_residence_id = new.Wall_rooms_Residence_residence_id
and r.room_abr = new.Wall_rooms_room_abr;
I have a MySQL database in which I have the following rows (by exemple) created by default (id, task and case may be different but the current value is always 1)
....idtaskcaseuser............datecurrent
238......31001.....0..............null..........1
239......41001.....0..............null..........1
I have to randomly create rows like this with insert statement (new rows). As you can see a date is filled and de current equal 0
....idtaskcaseuser............datecurrent
240......51001.....12015.04.03..........0
241......21002.....12015.04.03..........0
When I come across one of the lines created by default I want to use an update instead of an insert statement.
So I created the following procedure in MySQL
DELIMITER //
DROP PROCEDURE IF EXISTS FillProgress//
CREATE PROCEDURE FillProgress ( get_case INT(10),get_task INT(10), get_user INT(10) )
BEGIN
DECLARE test tinyint(1);
SET test = (SELECT COUNT(*) FROM progress WHERE case_id = get_case AND task_id = get_task);
IF test = 1 THEN
UPDATE progress SET current = 0, date = NOW(), user_id = get_user WHERE task_id = get_id AND case_id = get_case;
ELSE
INSERT INTO progress(task_id,case_id,user_id,date,current) VALUES (get_task,get_case,get_user,NOW(),0);
END IF;
END; //
DELIMITER ;
I use count to see if a already have a row with the same case and task. If it's true (test=1) I use UPDATE, otherwise and use INSERT.
If I test with the following row already wrote in the database
....idtaskcaseuserdatecurrent
241......41001.....0..null..........1
I use CALL FillProgress(1001,4,1);
The row is not updated, but I do not have any error message.
11:38:02 CALL FillProgress(1001,4,1) 0 row(s) affected 0.000 sec
And if I manually use my update query
UPDATE progress SET current = 0, date = NOW(), user_id = 1 WHERE task_id = 4 AND case_id = 1001;
It works like a charm.
The insert query also works fine.
The UPDATE query within the procedure has a "WHERE task_id = get_id" clause, however I don't see get_id being defined in the procedure; there is a "get_task" parameter for the stored procedure, though.