syntax error in mysql procedure error code 1064 - mysql

I am trying to write one procedure, i am getting syntax error. I was trying to fix the same with the help of net, but failed.
Here is my stored procedure. Any help please?
The scenario is i am trying to take workspaceid column values from table hotelings and trying to make that value as my column for another table. Then i am trying to update the same column value with ; for a given start and end time of hoteling table in newly created table2.
My two tables are
CREATE TABLE `hotelings` (
`HotelingId` int(11) NOT NULL AUTO_INCREMENT,
`Description` longtext,
`StartDate` datetime NOT NULL,
`EndDate` datetime NOT NULL,
`BookedBy` longtext,
`BookingType` int(11) NOT NULL,
`RepeatType` longtext,
`RepeatDay` longtext,
`ProjectId` int(11) NOT NULL,
`WorkSpaceId` int(11) NOT NULL,
`starttime` varchar(45) DEFAULT NULL,
`endtime` varchar(45) DEFAULT NULL,
PRIMARY KEY (`HotelingId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `hotelingtime` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Time` time DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
and my procedure is:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_procedure`()
BEGIN
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN workspaceid = ''',
workspaceid,
''' then "" ELSE NULL end) AS ',
CONCAT('`',workspaceid,'`')
)
) INTO #sql
FROM sms.hotelings;
SET #sql = CONCAT('CREATE TABLE IF NOT EXISTS table2 AS SELECT t.Time as Time, ', #sql, ' FROM sms.hotelings h, sms.hotelingtime t
GROUP BY t.Time');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
begin
declare num_rows int;
declare i int;
declare col_name varchar(50);
declare v varchar(10);
DECLARE v_finished INTEGER DEFAULT 0;
-- cursor to fetch column names
DECLARE col_names CURSOR FOR
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'table2'
ORDER BY ordinal_position;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN col_names;
temp_hotelingloop: LOOP
FETCH col_names INTO col_name;
IF v_finished = 1 THEN
LEAVE temp_hotelingloop;
END IF;
begin
declare starttime time;
declare endtime time;
-- cursor to fetch start and end for a given workspaceid
DECLARE startendTime CURSOR FOR
SELECT starttime, endtime from hotelings
where workspaceid = col_name;
OPEN startendTime;
FETCH startendTime INTO starttime, endtime;
-- i am getting error here and not giving me the result.
SET #sql = CONCAT('update table2 set ''',#col_name ,''' = '';'' where time between ''',#starttime,''' and ''',#endtime,'''');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CLOSE startendTime;
end;
SET i = i + 1;
END LOOP temp_hotelingloop;
CLOSE col_names;
end;
select * from table2;
DROP TABLE table2;
END
Any help please?
Thanks in advance

SET #sql = CONCAT('update table2 set ''',#col_name ,''' = '';'' where time between ''',#starttime,''' and ''',#endtime,'''');
You are using #col_name here, but on your declaration missing the #
declare col_name varchar(50);

Related

MySQL MyISAM query still optimized when the first column is null

In MySQL offcial document for count,there are descriptions as below:
For MyISAM tables, COUNT(*) is optimized to return very quickly if the SELECT retrieves from one > table, no other columns are retrieved, and there is no WHERE clause. For example:
mysql> SELECT COUNT(*) FROM student;
This optimization only applies to MyISAM tables, because an exact row count is stored for this >storage engine and can be accessed very quickly. COUNT(1) is only subject to the same >optimization if the first column is defined as NOT NULL.
I want to test it for myself, and make a test as below,I make a table called system_user and the first column is type,all the value of type is null,however when I use SELECT COUNT(1) and SELECT COUNT(*) to query, I found the time cost is nearly the same,even if tried for serval times.
I am wonder why the first column is null and the optimization in MyISAM is still working?
When I use SQL_NO_CACHE,the time cost is still nearly the same:
related table:
CREATE TABLE `system_user` (
`type` varchar(10) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(8) NOT NULL,
`age` int(11) DEFAULT NULL,
`tag` varchar(8) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
related procdure to create massive data:
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `add_user_batch`$$
CREATE DEFINER=`root`#`%` PROCEDURE `add_user_batch`(IN COUNT INT)
BEGIN
DECLARE i INT;
DECLARE t_name VARCHAR(8);
DECLARE t_tag VARCHAR(20);
DECLARE t_age INT(2);
DECLARE t_sql_template VARCHAR(100);
DECLARE t_sql TEXT;
DECLARE t_tag_mod_val INT DEFAULT(25);
DECLARE t_commit_mod_val INT DEFAULT(100);
DECLARE t_start_time DATETIME;
DECLARE t_end_time DATETIME;
TRUNCATE TABLE `system_user`;
SET t_start_time=NOW();
SET t_sql_template = “INSERT INTO `system_user`(NAME, age, tag) VALUES“;
SET t_sql = t_sql_template;
SET i = 1;
WHILE i <= COUNT
DO
SET t_age = FLOOR(1 + RAND() * 60);
SET t_name = LEFT(UUID(), 8);
IF MOD(i, t_tag_mod_val) = 0 THEN
SET t_tag = “NULL“;
ELSE
SET t_tag = CONCAT(“'“,LEFT(UUID(), 8),“'“);
END IF;
SET t_sql = CONCAT(t_sql,“('“,t_name,“',“,t_age,“,“,t_tag,“)“);
IF MOD(i,t_commit_mod_val) != 0 THEN
SET t_sql = CONCAT(t_sql,“,“);
ELSE
SET t_sql = CONCAT(t_sql,“;“);
SET #insert_sql = t_sql;
PREPARE stmt FROM #insert_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
COMMIT;
SET t_sql=t_sql_template;
END IF;
SET i = i + 1;
END WHILE;
IF LENGTH(t_sql) > LENGTH(t_sql_template) THEN
SET t_sql=CONCAT(SUBSTRING(t_sql,1,LENGTH(t_sql)-1),';');
SET #insert_sql = t_sql;
PREPARE stmt FROM #insert_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
COMMIT;
END IF;
SET t_end_time=NOW();
SELECT CONCAT('insert data success,time cost ',TIMEDIFF(t_end_time,t_start_time)) AS finishedTag;
END$$
DELIMITER ;

the count of row( user) for each table begining with cm in the schema

I want all the tables' list with corresponding count of number of NULL entries in column 'user'. I have printed all table's name beginning with cm using
SELECT
TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES WHERE (TABLE_NAME LIKE 'cm%') ;
but for each table i want to run
SELECT COUNT(1) FROM <TABLENAME> WHERE `create_user` IS NULL
OR `create_time` IS NULL
and print
Create the table below, replacing it with the correct database name:
CREATE TABLE `db`.`tbl_count_null` (
`tableschema` varchar(64) NOT NULL DEFAULT '',
`tablename` varchar(64) NOT NULL DEFAULT '',
`qtd` char(0) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
See if the procedure below meets you:
CREATE DEFINER=`user`#`%` PROCEDURE `nameprocedure`()
BEGIN
DECLARE x, y LONGTEXT;
DECLARE done INT DEFAULT 0;
DECLARE databasesCursor CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'cm%';
DECLARE CONTINUE HANDLER
FOR SQLSTATE '02000' SET done = 1;
OPEN databasesCursor;
myLoop: LOOP
FETCH databasesCursor INTO x, y;
IF NOT done THEN
SET #query = CONCAT("INSERT INTO`db`.`tbl_count_null` (tableschema, tablename, qtd) SELECT '",x,"' AS `schema`,'",y,"' AS `table`,COUNT(1) FROM `",x,"`.`",y,"` WHERE `create_user` IS NULL OR `create_time` IS NULL;");
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END LOOP myLoop;
CLOSE databasesCursor;
END;
After creating the above procedure, call with the command:
call db.nameprocedure;
Verify that the records have been inserted into the table db.tbl_count_null

Stored procedure for copying data

I am all new to creating procedures and triggers in MySQL, but have struggled with this over the last couple of days, and it simply will not work. The error messages, that I get from Mysql does not help me any longer.
So I am trying to create a procedure, which I need to run after an update. I will take any updates and store new data in a dynamic created table in another database.
Here it is:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
SET tablename = CONCAT('price_',#NUMBER);
SET #SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
This need to be triggered after update, where the SQL goes like:
CREATE TRIGGER copy_price_data AFTER UPDATE ON price
FOR EACH ROW
BEGIN
IF NEW.updated <> OLD.updated THEN
SET #market_id = NEW.fk_market_id;
SET #tablename = NULL;
CALL create_price_storage_table(#market_id, #tablename);
SELECT #tablename;
SET #SQL = CONCAT(
'INSERT INTO ',
#tablename,
' (`fk_market_id`, `fk_outcome_type_id`, `price`, `status`, `created`) VALUES (NEW.fk_market_id, NEW.fk_outcome_type_id, NEW.price, NEW.status, NOW())');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END;
When trying to create the procedure, then I get the following error message from MySQL:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
MySQL returnerede: Dokumentation 1064 - 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 '' at line 3
I hope someone with greater understanding than me, can point me in the right direction. Thanks.
Change:
CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
SET #NUMBER = CEILING(market_id / 100000) * 100000;
SET tablename = CONCAT('price_',#NUMBER);
SET #SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
By:
CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
BEGIN
DECLARE `NUMBER` INT UNSIGNED;
SET `NUMBER` := CEILING(`market_id` / 100000) * 100000;
SET `tablename` := CONCAT('`price_', NUMBER, '`');
SET #`SQL` := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
`pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_market_id` INT(11) UNSIGNED NOT NULL,
`fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
`price` DOUBLE NOT NULL,
`status` ENUM(\'enabled\',\'disabled\') NOT NULL,
`created` DATETIME NOT NULL,
PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8');
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
PREPARE `stmt` FROM #`SQL`;
EXECUTE `stmt`;
DEALLOCATE PREPARE `stmt`;
END//
Example:
mysql> DROP PROCEDURE IF EXISTS `get_price_storage_table`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
-> BEGIN
-> DECLARE `NUMBER` INT UNSIGNED;
-> SET `NUMBER` := CEILING(`market_id` / 100000) * 100000;
-> SET `tablename` := CONCAT('`price_', NUMBER, '`');
-> SET #`SQL` := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
> `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
> `fk_market_id` INT(11) UNSIGNED NOT NULL,
> `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
> `price` DOUBLE NOT NULL,
> `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
> `created` DATETIME NOT NULL,
> PRIMARY KEY (`pk_id`)
> ) ENGINE=InnoDB DEFAULT CHARSET=utf8');
-> PREPARE `stmt` FROM #`SQL`;
-> EXECUTE `stmt`;
-> DEALLOCATE PREPARE `stmt`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `get_price_storage_table`(1, #`tablename`);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #`tablename`;
+----------------+
| #`tablename` |
+----------------+
| `price_100000` |
+----------------+
1 row in set (0.00 sec)
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| price_100000 |
+----------------+
1 row in set (0.00 sec)
Syntax errors are to be located to the left (or above) of the place reported in the error message, since the reported place is the first thing that confuses MySQL.
In your case this is the ;
It finishes your CREATE PROCEDURE statement, but MySQL expects more to come, like an END.
Procedures / Triggers / Functions have to be declared with a different delimiter when they consist of more than one statement.
Try like this:
DELIMITER $$
CREATE PROCEDURE whatever()
BEGIN
SELECT 'whatever';
SELECT 'another';
END $$
DELIMITER ;

Mysql use LAST_INSERT_ID in stored procedure

I need to create a table based on the last id inserted into another main table, for this I created the following stored procedure:
CREATE PROCEDURE `sp_create_campaign`
(
IN p_vName VARCHAR(70),
IN p_iIdOper INT(11),
IN p_iIdCount INT(11),
IN p_iIdMoney INT(11),
IN p_cPrefix CHAR(2),
IN p_tComment TINYTEXT,
IN p_iIdUser VARCHAR(32),
OUT p_return_code TINYINT UNSIGNED
)
BEGIN
DECLARE p_campaign INT(11);
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
DECLARE exit handler for sqlwarning
BEGIN
-- WARNING
set p_return_code = 2;
rollback;
END;
START TRANSACTION;
-- Campaign
INSERT INTO `db_campaign`
(`vName`, `iIdOper`, `iIdCount`, `iIdMoney`, `cPrefix`, `tComment`, `iIdUser`, `dRegister`)
VALUES
(p_vName, p_iIdOper, p_iIdCount, p_iIdMoney, p_cPrefix, p_tComment, p_iIdUser, NOW());
SET p_campaign := LAST_INSERT_ID();
-- Sales
SET #s = CONCAT('DROP TABLE IF EXISTS ', 'db_sale_', p_campaign);
PREPARE stm FROM #s;
EXECUTE stm;
SET #x = CONCAT(
'CREATE TABLE ',
'db_sale_', p_campaign,
"(
`iIdSale` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`dDate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`dSubtotal` DECIMAL(7,2) UNSIGNED NOT NULL DEFAULT '00.00',
`dTax` DECIMAL(7,2) UNSIGNED NOT NULL DEFAULT '00.00',
`dTotal` DECIMAL(7,2) UNSIGNED NOT NULL DEFAULT '00.00',
`iIdMoney` INT(11) UNSIGNED NOT NULL,
`iIdOper` INT(11) UNSIGNED NOT NULL,
`iIdBankCount` INT(11) UNSIGNED NOT NULL,
`iIdGroup` INT(11) UNSIGNED NOT NULL,
`iIdUser` INT(11) UNSIGNED NOT NULL,
`iIdUserReg` VARCHAR(32) NOT NULL,
`dRegister` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`iIdSale`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
PREPARE stm FROM #x;
EXECUTE stm;
COMMIT;
-- SUCCESS
set p_return_code = 0;
END
But the problem is that only inserts the first record and fails to create the table. Where am I failing?
Replace this line: SET p_campaign := LAST_INSERT_ID();
With this one: SELECT LAST_INSERT_ID() INTO p_campaign ;
if you use SET you need = instead of :=
Two things:
Executing DROP will implicitly COMMIT your transaction.
Try adding
DEALLOCATE PREPARE stm;
after each EXECUTE statement.
According to MySQL documentation of last_insert_id()
If a stored procedure executes statements that change the value of LAST_INSERT_ID(), the changed value is seen by statements that follow the procedure call.
Use something like:
SELECT id INTO p_campaign FROM db_campaign ORDER BY id DESC LIMIT 1;
Or:
SELECT max(id) INTO p_campaign FROM db_campaign;

Split strings using mysql

I want to create a stored procedure which will do matching of two tables. My requirement is to match two tables based on the columns user passes as an input.
Syntax:
CREATE PROCEDURE reconcile.matchTables(
IN TAB1 VARCHAR(25),
IN TAB1 VARCHAR(25),
IN COLS1 VARCHAR(250) ,
IN COLS2 VARCHAR(250))
EX:
matchTables('table1', 'table2', 'col1#col2#col3#col4' , 'col2#col13#col1#col8')
Now the stored procedure should form the where clause like the following
table1.col1 = table2.col2
and table1.col2 = table2.col13
and table1.col3 = table2.col1
and table1.col4 = table2.col8
MySQL does not include a function to split a delimited string. However, it’s very easy to create your own function.
User define function:
CREATE [AGGREGATE] FUNCTION function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL}
Function:
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
Usage:
SELECT SPLIT_STR(string, delimiter, position)
Answer
Table 1
CREATE TABLE `Table1` (
`Col1` varchar(100) DEFAULT NULL,
`Col2` varchar(100) DEFAULT NULL,
`Col3` varchar(100) DEFAULT NULL,
`Col4` varchar(100) DEFAULT NULL,
`DummyColumn` varchar(45) DEFAULT NULL
)
Table 2
CREATE TABLE `Table2` (
`col2` varchar(100) DEFAULT NULL,
`col13` varchar(100) DEFAULT NULL,
`col1` varchar(100) DEFAULT NULL,
`col8` varchar(100) DEFAULT NULL
)
Stored Procedure
CREATE DEFINER=`Connect7827`#`%` PROCEDURE `reconcile.matchTables`(
IN TAB1 VARCHAR(25),
IN TAB2 VARCHAR(25),
IN COLS1 VARCHAR(250) ,
IN COLS2 VARCHAR(250))
StartfromHere: BEGIN
DECLARE NoOfColumnInTable1 INT unsigned DEFAULT 0;
DECLARE NoOfColumnInTable2 INT unsigned DEFAULT 0;
Declare Column1Count int default 1;
Declare Column2Count int default 1;
Declare vPickOneValue varchar(100);
Declare querystring varchar(8000);
Declare NoOFRowsInFinalResult int default 1;
Declare _Tab1 varchar(1000);
Declare _TAB2 varchar(1000);
Declare _COLS1 varchar(1000);
Declare _COLS2 varchar(1000);
-- Column Names for Table 1
DROP TEMPORARY TABLE IF EXISTS Table1_Columns;
CREATE TEMPORARY TABLE Table1_Columns(Column_Name varchar(100));
SET #buffer= CONCAT_WS('','insert into Table1_Columns(Column_Name)
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = ',"'",TAB1,"'");
-- Select #buffer;
PREPARE stmt FROM #buffer;
EXECUTE stmt;
-- Column Names for Table 2
DROP TEMPORARY TABLE IF EXISTS Table2_Columns;
CREATE TEMPORARY TABLE Table2_Columns(Column_Name varchar(100));
SET #buffer= CONCAT_WS('','insert into Table2_Columns(Column_Name)
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = ',"'",TAB2,"'");
-- Select #buffer;
PREPARE stmt FROM #buffer;
EXECUTE stmt;
Set NoOfColumnInTable1=(Select count(*) from Table1_Columns);
Set NoOfColumnInTable2=(Select count(*) from Table2_Columns);
-- Select NoOfColumnInTable1,NoOfColumnInTable2;
if (NoOfColumnInTable1=0) then
Select 'Table 1 not found in database'as'Result';
leave StartfromHere;
end if;
if (NoOfColumnInTable2=0) then
Select 'Table 2 not found in database' as'Result' ;
leave StartfromHere;
end if;
IF (NoOfColumnInTable1!=NoOfColumnInTable2) then
Select 'No of column to be joined must be equal.'as'Result';
leave StartfromHere;
end if;
DROP TEMPORARY TABLE IF EXISTS BasedOn_Col1_List;
CREATE TEMPORARY TABLE BasedOn_Col1_List(ID int NOT NULL AUTO_INCREMENT, Column_Name varchar(100), PRIMARY KEY (id));
while Column1Count< NoOfColumnInTable1+1 do
set #Query=CONCAT_WS('' ,"insert into BasedOn_Col1_List(Column_Name) Select SUBSTRING_Index('",COLS1,"','#',",Column1Count,");");
-- Select #Query as'Value';
PREPARE stmt1 FROM #Query;
EXECUTE stmt1;
SET Column1Count=Column1Count+1;
end while;
SET Column1Count=1;
WHILE Column1Count<=NoOfColumnInTable1 do
SET vPickOneValue=(Select Concat(Column_Name,"#") from BasedOn_Col1_List where ID=Column1Count);
update BasedOn_Col1_List set Column_Name=replace(Column_Name,vPickOneValue,"") where ID<>Column1Count;
-- Select vPickOneValue;
SET Column1Count=Column1Count+1 ;
end while;
-- Preapre Table from Column2 Parameter
DROP TEMPORARY TABLE IF EXISTS BasedOn_Col2_List;
CREATE TEMPORARY TABLE BasedOn_Col2_List(ID int NOT NULL AUTO_INCREMENT, Column_Name varchar(100), PRIMARY KEY (id));
while Column2Count< NoOfColumnInTable2+1 do
set #Query=CONCAT_WS('' ,"insert into BasedOn_Col2_List(Column_Name) Select SUBSTRING_Index('",COLS2,"','#',",Column2Count,");");
-- Select #Query as'Value';
PREPARE stmt2 FROM #Query;
EXECUTE stmt2;
SET Column2Count=Column2Count+1;
end while;
SET Column2Count=1;
WHILE Column2Count<=NoOfColumnInTable2 do
SET vPickOneValue=(Select Concat(Column_Name,"#") from BasedOn_Col2_List where ID=Column2Count);
update BasedOn_Col2_List set Column_Name=replace(Column_Name,vPickOneValue,"") where ID<>Column2Count;
-- Select vPickOneValue;
SET Column2Count=Column2Count+1 ;
end while;
DROP TEMPORARY TABLE IF EXISTS TableFromColumnList;
CREATE TEMPORARY TABLE TableFromColumnList
( ID int NOT NULL AUTO_INCREMENT,
Table1Name varchar(100),
Column_Name_Table1 varchar(100),
Table2Name varchar(1000),
Column_Name_Table2 varchar(100),
PRIMARY KEY (id)
);
Insert into TableFromColumnList(Column_Name_Table1,Column_Name_Table2,Table1Name,Table2Name)
select t1.Column_Name,t2.Column_Name,TAB1,TAB2
from BasedOn_Col1_List t1 , BasedOn_Col2_List t2 where t1.Id=t2.id;
-- -- Preparing the final Result ----------------
While NoOFRowsInFinalResult<=NoOfColumnInTable2 do -- / Or NoOFRowsInFinalResult<=NoOfColumnInTable2 --
SET _Tab1 =(Select Table1Name from TableFromColumnList where Id=NoOFRowsInFinalResult);
SET _COLS1 =(Select Column_Name_Table1 from TableFromColumnList where Id=NoOFRowsInFinalResult);
SET _TAB2 =(Select Table2Name from TableFromColumnList where Id=NoOFRowsInFinalResult);
SET _COLS2 =(Select Column_Name_Table2 from TableFromColumnList where Id=NoOFRowsInFinalResult);
IF NoOFRowsInFinalResult=1 then
SET querystring =concat_ws("" , querystring,_Tab1,".", _COLS1 , "=",_Tab2,".", _COLS2," ");
else
SET querystring =concat_ws("" , querystring ,"and",_Tab1,".", _COLS1 , "=" ,_Tab2,".", _COLS2 ," ");
end if;
SET NoOFRowsInFinalResult=NoOFRowsInFinalResult+1 ;
End while;
SET querystring=concat_ws("","Select * from ",TAB1,", " ,TAB2," where ",querystring);
Select querystring;
END
CREATE PROCEDURE matchTables
#TAB1 VARCHAR(25),
#TAB2 VARCHAR(25),
#COLS1 VARCHAR(250) ,
#COLS2 VARCHAR(250)
AS
BEGIN
DECLARE #WHEREstring VARCHAR(MAX)
SET #WHEREstring =
'
WHERE
'
SELECT #WHEREstring = #WHEREstring + #TAB1 +'.'+ tab1.col+' = '+#TAB2+'.' + tab2.col +' AND
'
FROM
(
SELECT QUOTENAME(split.a.value('.','VARCHAR(100)')) AS col, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum
FROM
(
SELECT Cast ('<M>' + Replace(#COLS1, '#', '</M><M>')+ '</M>' AS XML) AS Tab1Data
) AS A
CROSS apply Tab1Data.nodes ('/M') AS Split(a)
) tab1
INNER JOIN
(
Select QUOTENAME(AliasSplit.c.value('.', 'varchar(100)')) AS col, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum
FROM
(
SELECT Cast ('<A>' + Replace(#COLS2, '#', '</A><A>')+ '</A>' AS XML) AS Tab2Data
) AS A
CROSS apply Tab2Data.nodes ('/A') AS AliasSplit(c)
) tab2
ON tab1.RowNum = tab2.RowNum
SET #WHEREstring= LEFT(#WHEREstring, LEN(#WHEREstring) - 8)
print #WHEREstring
END
Now, execute it using :::
EXEC matchTables 'table1', 'table2', 'col1#col2#col3#col4' , 'col2#col13#col1#col8'
i hope you got the desired where clause. cheers
You can build your own function:
CREATE FUNCTION String_split(inp VARCHAR(255),del VARCHAR(255),loc INT)
RETURNS VARCHAR(255)
RETURN REPLACE(Substring(Substring_index(inp, del,loc),LENGTH(Substring_index(inp, del, loc-1)) + 1),del, '');
CHAR_LENGTH - return correct length in chars
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
CHAR_LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');