I have this MySQL Stored Procedure
DELIMITER $$
CREATE DEFINER=`dbuser`#`%` PROCEDURE `getTranslatedAnswer`(IN questionDesc VARCHAR(2500), col VARCHAR(10))
BEGIN
SET #paramVal = questionDesc;
SET #str = CONCAT('SELECT C.',col,' AS `answer`, D.',col,' AS `message`
FROM `option_group` A
INNER JOIN `questions_answers` B ON A.`option_id` = B.`option_id`
INNER JOIN `answers` C ON B.`answers_id` = C.`answers_id`
INNER JOIN `chat_message` D ON A.`option_group_id` = D.`option_group_id`
WHERE UPPER(`A`.',col,') = ? LIMIT 1');
PREPARE stmt FROM #str;
EXECUTE stmt USING #paramVal;
DEALLOCATE PREPARE stmt;
END
The above code when called using
call getTranslatedAnswer('我可以在机场买到预付SIM卡吗?','zh_chs');
will return 0 rows. Compared to as when I call the bare SQL below
SELECT C.zh_chs AS `answer`, D.zh_chs AS `message`
FROM `option_group` A
INNER JOIN `questions_answers` B ON A.`option_id` = B.`option_id`
INNER JOIN `answers` C ON B.`answers_id` = C.`answers_id`
INNER JOIN `chat_message` D ON A.`option_group_id` = D.`option_group_id`
WHERE UPPER(`A`.`zh_chs`) = '我可以在机场买到预付SIM卡吗?' LIMIT 1;
it returns 1 row. Am I missing something here? How do I debug this? Please advise, thanks!
I could be remembering wrong, but I seem to recall execute not actually returning results as you expecting it to.
What happens if you try something like this?
DELIMITER $$
CREATE DEFINER=`dbuser`#`%` PROCEDURE `getTranslatedAnswer`(IN questionDesc VARCHAR(2500), col VARCHAR(10))
BEGIN
SET #paramVal = questionDesc;
DROP TEMPORARY TABLE IF EXISTS `t_getTranslatedAnswer`;
SET #str = CONCAT('
CREATE TEMPORARY TABLE `t_getTranslatedAnswer`
SELECT C.',col,' AS `answer`, D.',col,' AS `message`
FROM `option_group` A
INNER JOIN `questions_answers` B ON A.`option_id` = B.`option_id`
INNER JOIN `answers` C ON B.`answers_id` = C.`answers_id`
INNER JOIN `chat_message` D ON A.`option_group_id` = D.`option_group_id`
WHERE UPPER(`A`.',col,') = ? LIMIT 1');
PREPARE stmt FROM #str;
EXECUTE stmt USING #paramVal;
DEALLOCATE PREPARE stmt;
SELECT * FROM `t_getTranslatedAnswer`;
DROP TEMPORARY TABLE `t_getTranslatedAnswer`;
END
Related
I apologize in advance, I'm not good at sql.
I want to do something very simple in a sql procedure but I'm stuck :
SELECT donnee.id_enregistrement, ',#col_createur, #col_date_creation, #col_date_derniere_modification, #COLUMNS
FROM ta_donnee_champ donnee
In the variable #COLUMNS there is a list of id, that I search in the table "ta_donnee_champ donnee".
I also want to use the same list of id to search in another table in the same query.
How can I put that in an inner join?
Like something like this :
SELECT donnee.id_enregistrement, ',#col_createur, #col_date_creation, #col_date_derniere_modification, #COLUMNS,'
FROM ta_donnee_champ donnee
INNER JOIN ta_champ_tableau ct
ON ct.id_champ_colonne IN (#COLUMNS)
Can someone give me a simple explanation please?
******************************EDIT********************************
In this procedure #COLUMNS represents columns of the desired results.
To these columns, I need to add values, the following code works :
IF #COLUMNS IS NOT NULL THEN
SET #SQL = CONCAT(
'SELECT donnee.id_enregistrement, ',#col_createur, #col_date_creation, #col_date_derniere_modification, #COLUMNS,'
FROM ta_donnee_champ donnee
INNER JOIN t_enregistrement enregistrement
ON donnee.id_enregistrement = enregistrement.id_enregistrement
WHERE donnee.id_enregistrement IN (',IFNULL(p_id_enregistrement, 'donnee.id_enregistrement'),')
AND donnee.id_enregistrement in (
select DISTINCT id_enregistrement from ta_participant
where id_groupe = ', p_id_groupe,'
or id_groupe in (
select id_groupe_lu
from ta_droits_groupe
inner join t_groupe on ta_droits_groupe.id_groupe_lu = t_groupe.id_groupe
where id_groupe_lecteur = ', p_id_groupe,'
and t_groupe.id_application = ', p_id_application,'
)
)
GROUP BY donnee.id_enregistrement'
);
-- Prépare et exécute la requête
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
My question is : I need to add another table from which I must know that ids are inside. How do I proceed best to search not only for id's in ta_donnee_champ donnee but also in another table?
How is #COLUMNS set :
SET #COLUMNS = NULL;
IF p_autoriser_tableau = 1 THEN
SET #filtre = 'SELECT DISTINCT id_champ_colonne FROM ta_champ_tableau';
ELSE
SET #filtre = 'SELECT DISTINCT id_champ_tableau AS id_champ FROM ta_champ_tableau UNION SELECT DISTINCT id_champ_colonne FROM ta_champ_tableau';
END IF;
-- Construit les colonnes à horizontaliser
SET #SQL1 = CONCAT('
SELECT GROUP_CONCAT(
DISTINCT CONCAT(
\'GROUP_CONCAT(IF(donnee.id_champ = \',
champ.id_champ ,
\', donnee.valeur, NULL)) AS `\',
champ.id_champ,\'`\'
)ORDER BY onglet.ordre, section.ordre, champ.ordre
) INTO #COLUMNS
FROM t_champ champ
INNER JOIN t_section section
ON section.id_section = champ.id_section
INNER JOIN t_onglet onglet
ON onglet.id_onglet = section.id_onglet
INNER JOIN ta_droits_champ droits_champ
ON droits_champ.id_groupe IN (
SELECT id_groupe FROM ta_agent_groupe WHERE id_agent = ', p_id_agent,'
)
AND droits_champ.id_champ = champ.id_champ
where onglet.id_application IN (', p_id_application,')
AND droits_champ.voir = 1
AND champ.id_champ NOT IN (',#filtre,')
AND
(
champ.date_fin_validite IS NULL
OR
date_format(champ.date_fin_validite, "%Y-%m-%d") > COALESCE(str_to_date("', p_date_validite,'", "%d/%m/%Y"), "01/01/1900")
)
;');
PREPARE stmt FROM #SQL1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Please some one help me tI have two Tables in my MYSQL database,
the first table - (Employee Table) consists of
EmployeeNo| EmployeeName
the second table - (Attendance table) consists of
DATE | TIME | STATUS| EmployeeNo
and a calendar table that holds only date for every month
I want to generate attendance sheet similar to this
Click here
I end up writing the following SQL, but it gives me syntax error
#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 'from (select cal.calendarDate,
emp.first_name,emp.nu' at line 2
and my query ,
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(CASE WHEN calemp.calendarDate = ''',date_format(calendarDate, '%Y-%m-%d'),''' THEN coalesce(att.inorout, ''P'') END) AS `',date_format(calendarDate, '%Y-%m-%d'), '`'
)
) INTO #sql
FROM yearly_date_calendar
where calendarDate >= '2016-11-01'
and calendarDate <= '2016-11-30';
SET #sql = CONCAT('SELECT calemp.first_name,calemp.nurse_code,',#sql,'
from
(
select cal.calendarDate,emp.first_name,emp.nurse_code
from yearly_date_calendar cal
cross join syscare_caregiver emp
) calemp
left join syscare_employee_attendance att
on calemp.nurse_code = att.emp_code
and calemp.calendarDate = att.attendance_date
where calemp.calendarDate>=''2016-11-01''
and calemp.calendarDate <= ''2016-11-30''
group by calemp.first_name, calemp.nurse_code,calemp.calendarDate
');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
You can use below query and fetch all database result
select EmployeeTable.EmployeeNo,Employee Table.EmployeeName,Attendance table.DATE,Attendance table.TIME,Attendance table.STAUS,Attendance table.EmployeeNo from Employee Table INNER JOIN Attendance table ON
EmployeeTable.EmployeeNo=Attendance table.EmployeeNo
I am using IBatis and Spring framework.
I would like to execute multi queries but I could not get the response.
<select id="getUIs" resultMap="blpUiVOMap" parameterClass="Map">
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('COUNT(CASE WHEN bug.BUG_STT = ', STT_ID, ' THEN 1 END) AS ''bugI', STT_ID, '''')
) INTO #sql
from BLP_STT <![CDATA[;]]>
SET #sql = CONCAT('SELECT ui.UI_ID, ui.UI_NM, cat.CAT_ID, cat.CAT_NM, cat.PRNT_ID, cat1.CAT_NM as PRNT_NM,',#sql,'FROM BLP_UI ui JOIN BLP_CAT cat ON ui.CAT_ID = cat.CAT_ID JOIN BLP_CAT cat1 ON cat.PRNT_ID = cat1.CAT_ID JOIN BLP_BUG bug ON ui.UI_ID = bug.UI_ID JOIN BLP_STT stt ON bug.BUG_STT = stt.STT_ID WHERE 1 = 1 GROUP BY ui.UI_ID ORDER BY ui.UI_ID ASC') <![CDATA[;]]>
PREPARE stmt FROM #sql <![CDATA[;]]>
EXECUTE stmt <![CDATA[;]]>
DEALLOCATE PREPARE stmt <![CDATA[;]]>
</select>
In MySQL, this query is working fine.
The <select> will create a single PreparedStatement in JDBC. You are trying to execute commands from the MySQL command line. This won't work in JDBC or MyBatis.
You will need to create a single query that combines all your strings. Maybe something like this?
SELECT ui.UI_ID, ui.UI_NM, cat.CAT_ID, cat.CAT_NM, cat.PRNT_ID, cat1.CAT_NM as PRNT_NM,
(SELECT
GROUP_CONCAT(DISTINCT
CONCAT('COUNT(CASE WHEN bug.BUG_STT = ', STT_ID, ' THEN 1 END) AS ''bugI', STT_ID, '''')
)
from BLP_STT
)
FROM BLP_UI ui JOIN BLP_CAT cat ON ui.CAT_ID = cat.CAT_ID JOIN BLP_CAT cat1 ON cat.PRNT_ID = cat1.CAT_ID JOIN BLP_BUG bug ON ui.UI_ID = bug.UI_ID JOIN BLP_STT stt ON bug.BUG_STT = stt.STT_ID WHERE 1 = 1 GROUP BY ui.UI_ID ORDER BY ui.UI_ID ASC')
Note, you also do not need to put a ; in the XML either.
I have a stored procedure and it's running slow. Is there a better way to pass the table id's to the procedure rather that use FIND_IN_SET?
The table column e.fk_trans_history_id is an INT(32)
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `1_trans_hist_ent_items_sel`(b INT,tid TEXT)
BEGIN
SELECT
e.id,
e.fk_trans_history_id,
e.fk_prod_pack_id,
e.line_num,
e.vat_code,
e.code,
e.make,
e.model,
e.price,
e.discount,
e.cover,
e.warranty,
p.make,
p.model,
p.weight,
p.width,
p.depth,
p.height,
p.cost,
p.cover_value_each,
p.web_model,
k.stock - k.repair
FROM
1_trans_history_entries e
LEFT JOIN
1_products p ON p.id = e.fk_prod_pack_id
AND LEFT(code, 1) <> 'P'
LEFT JOIN
1_stock k ON k.fk_products_id = p.id AND k.branch = b
WHERE
(e.code IN ('MiscShip' , 'Collect')
OR (ASCII(e.code) > 47
AND ASCII(e.code) < 58))
AND FIND_IN_SET(e.fk_trans_history_id, tid)
ORDER BY e.id;
END
Put the IDs you want to match into a temporary table, and join with that table.
CREATE TEMPORARY TABLE temp_trans_hist_ent_items_sel_ids (
id
);
INSERT INTO temp_trans_hist_ent_items_sel_ids VALUES (1), (10), ...;
Then the query in the procedure can use:
JOIN temp_trans_hist_ent_items_sel_ids AS temp ON e.fk_trans_history_id = temp.id
I found the best and the fastest is to prepare a query like this.
CREATE DEFINER=`root`#`localhost` PROCEDURE `1_trans_hist_ent_items_sel`(b INT, tid TEXT)
BEGIN
--
SET #query=CONCAT( '
SELECT
e.id,
e.fk_trans_history_id,
e.fk_prod_pack_id,
e.line_num,
e.vat_code,
e.code,
e.make,
e.model,
e.price,
e.discount,
e.cover,
e.warranty,
p.make,
p.model,
p.weight,
p.width,
p.depth,
p.height,
p.cost,
p.cover_value_each,
p.web_model,
k.stock - k.repair
FROM
1_trans_history_entries e
LEFT JOIN
1_products p ON p.id = e.fk_prod_pack_id
AND LEFT(code, 1) <> \'P\'
LEFT JOIN
1_stock k ON k.fk_products_id = p.id AND k.branch = ',b,'
WHERE
(e.code IN (\'MiscShip\' , \'Collect\')
OR (ASCII(e.code) > 47
AND ASCII(e.code) < 58))
AND e.fk_trans_history_id IN(' , tid , ')
ORDER BY e.id;');
--
PREPARE sql_query FROM #query;
EXECUTE sql_query;
--
SET #query = '';
--
END
Thanks to Stephen Bouffe. My code is shorter and it would be easier to understand and implement this solution. In my case, it looks like this
SET #query=CONCAT( '
DELETE FROM markup
WHERE id IN (', #ids, ');
');
PREPARE sql_query FROM #query;
EXECUTE sql_query;
Where #ids is a string like '7,12,52'.
It works significantly faster then FIND_IN_SET.
I have the following code:
SELECT 'UPDATE table3 ENTRYNAME = '''+CONVERT(VARCHAR(5000),
riv.description)+''''+' WHERE id = '+CONVERT(VARCHAR(50), e.ID)+';' AS
Update_Statement
FROM table1 AS riv
JOIN table2 AS e
ON riv.Code = e.Code
AND riv.definitioncode = 'RIV'
AND riv.Description <> e.Description
AND riv.categoryID <> 0
;
This generates column values that look like this:
UPDATE table3 SET ENTRYNAME = 'new column data here' WHERE id = 50005;
I want to be able run the column data after it is generated.
How would I go about doing this?
Could it look something like this:
DECLARE #update_Statement --update statement
DECLARE db_cursor CURSOR FOR
SELECT 'UPDATE table3 ENTRYNAME = '''+CONVERT(VARCHAR(5000),
riv.description)+''''+' WHERE id = '+CONVERT(VARCHAR(50), e.ID)+';' AS
Update_Statement
FROM table1 AS riv
JOIN table2 AS e
ON riv.Code = e.Code
AND riv.definitioncode = 'RIV'
AND riv.Description <> e.Description
AND riv.categoryID <> 0
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #update_statement
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE #update_statement
END
CLOSE db_cursor
DEALLOCATE db_cursor