I have written a stored procedure in mysql which will create a TEMPORARY TABLE, I want to access the data of TEMPORARY TABLE using Codeigniter.But when I call "$this->db->query()" it returns empty data.
$data=array();
$call_procedure = "CALL sp_Stock()";
$query = $this->db->query($call_procedure);
$sql="SELECT * FROM StockTable";
$query1 = $this->db->query($sql);
I have changed my way to show the data. And I do changes it on stored procedure.
DELIMITER $$
CREATE PROCEDURE sp_Stock()
BEGIN
DECLARE cursor_finish INTEGER DEFAULT 0;
DECLARE m_numofpurchaseBag DECIMAL(10,2)DEFAULT 0;
DECLARE m_purchasedKg DECIMAL(10,2)DEFAULT 0;
DECLARE m_purBagDtlId INTEGER DEFAULT 0;
DECLARE stockCursor CURSOR FOR
SELECT purchase_bag_details.`actual_bags`,
(purchase_bag_details.`net`*purchase_bag_details.`actual_bags`) AS PurchasedKg,
purchase_bag_details.`id` AS PurchaseBagDtlId
FROM
purchase_invoice_detail
INNER JOIN
purchase_bag_details
ON purchase_invoice_detail.`id`= purchase_bag_details.`purchasedtlid`
INNER JOIN
`do_to_transporter`
ON purchase_invoice_detail.`id` = do_to_transporter.`purchase_inv_dtlid`
WHERE purchase_invoice_detail.`teagroup_master_id`=6
AND purchase_invoice_detail.`id`=1481
AND do_to_transporter.`in_Stock`='Y';
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET cursor_finish = 1;
DROP TEMPORARY TABLE IF EXISTS StockTable;
#temptable creation
CREATE TEMPORARY TABLE IF NOT EXISTS StockTable
(
purchaseBagDtlId INT,
purchasedBag NUMERIC(10,2),
purchasedKg NUMERIC(10,2),
blendedBag NUMERIC(10,2),
blendedKg NUMERIC(10,2),
stockBag NUMERIC(10,2),
stockKg NUMERIC(10,2)
);
#temptable creation
OPEN stockCursor ;
get_stock : LOOP
FETCH stockCursor INTO m_numofpurchaseBag,m_purchasedKg,m_purBagDtlId;
IF cursor_finish = 1 THEN
LEAVE get_stock;
END IF;
/*SELECT m_numofpurchaseBag,m_purchasedKg,m_purBagDtlId; */
/* Blending bag query*/
SET #m_numberofBlndBag:=0;
SET #m_BlndKg:=0;
/* Blend bag*/
SELECT #m_numberofBlndBag:=SUM(blending_details.`number_of_blended_bag`) AS belendedBag INTO #m_numberofBlndBag
FROM blending_details
WHERE blending_details.`purchasebag_id`= m_purBagDtlId
GROUP BY
blending_details.`purchasebag_id`;
#Blend Bag
#Blend Kgs
SELECT #m_BlndKg:=SUM(blending_details.`qty_of_bag` * blending_details.`number_of_blended_bag`) AS blendkg INTO #m_BlndKg
FROM blending_details
WHERE blending_details.`purchasebag_id`= m_purBagDtlId
GROUP BY
blending_details.`purchasebag_id`;
SET #m_StockBag:=(m_numofpurchaseBag - #m_numberofBlndBag);
SET #m_StockKg:=(m_purchasedKg - #m_BlndKg);
INSERT INTO StockTable
(
purchaseBagDtlId ,
purchasedBag ,
purchasedKg ,
blendedBag ,
blendedKg ,
stockBag ,
stockKg
)VALUES(m_purBagDtlId,m_numofpurchaseBag,m_purchasedKg,#m_numberofBlndBag,#m_BlndKg,#m_StockBag,#m_StockKg);
END LOOP get_stock;
CLOSE stockCursor;
SELECT * FROM StockTable;
#DROP TABLE StockTable;
END$$
DELIMITER ;
#CALL sp_Stock();
Anywhere I am using a temp table I am executing this before the temp table is created:
$this->db->query('DROP TABLE IF EXISTS StockTable');
I seem to remember reading someone having the same problem as you and for some reason you have to execute the above first.
So try:
$data=array();
$call_procedure = "CALL sp_Stock()";
$this->db->query('DROP TABLE IF EXISTS StockTable');
$query = $this->db->query($call_procedure);
$sql="SELECT * FROM StockTable";
$query1 = $this->db->query($sql);
Related
I'm trying to generate URL in SQL database using already assigned auto_incremented ID
When a new form is submitted then SQL automatically generates and unique lens_id for me. How can I automatically add it there in this lens_url? (Picture below)
You can do this by creating a trigger on your table. Trigger is as follows,
DELIMITER $$
CREATE TRIGGER `UpdateLensURL` BEFORE INSERT ON `your_table_name`
FOR EACH ROW BEGIN
SET NEW.lens_url= CONCAT('localhost:8888/lensview/post.php?id=', (
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'your_table_name'
));
END;
$$
DELIMITER ;
There are two options here:
1) Use a stored procedure (which will require code changes for anywhere that inserts rows)
2) Use a trigger and insert as normal - something like below should do the trick:
DELIMITER //
CREATE TRIGGER my_awesome_trigger
BEFORE INSERT
ON your_table_name
FOR EACH ROW
BEGIN
DECLARE next_id int default 0;
SELECT auto_increment INTO next_id
FROM information_schema.tables
WHERE table_name = 'your_table_name'
AND table_schema = DATABASE();
SET NEW.lens_url = CONCAT('localhost:8888/.../', next_id);
END; //
DELIMITER ;
Try something like this
$qry1="insert into tablename(lens_name,lens_url,lens_category,lens_author,lens_discription,lens_repert)values('A','B','C','D','E','F')";// your query to insert data to table
mysqli_query($con,$qry1); // run query
$last_insertid=mysqli_insert_id($con); // save last insetred ID
$url="localhost:8888/lenseview/post.php?id=".$last_insertid; //prepare url
$qry2="upadte tablename set lens_url=$url where lens_id=$last_insertid"; //update query
mysqli_query($con,$qry2); // run your query to update url
I think easiest option would be this
$Last_Lens_IdQ = mysqli_query($conn, "SELECT `lens_id` FROM `table` ORDER BY `lens_id` DESC LIMIT 1");
$Last_LensId = mysqli_fetch_array($Last_Lens_IdQ);
$x = $Last_Lens[0]++;
$LensUrl = "localhost:8888/lenseview/post.php?id=".$x;
Then insert the field and use $LensUrl When inserting the lens url column
$link->query("DROP TABLE IF EXISTS table2");
$link->query("CREATE TABLE table2 (newcol BIGINT UNSIGNED PRIMARY KEY)");
$result=$link->query("select col1 from table1");
while($data=$result->fetch_array(MYSQL_ASSOC))
{
$link->query("insert into table2 (newcol) values($data['col1']);
$link->query(""ALTER TABLE table2 ADD `".$data['col1']."` BIGINT DEFAULT 0"");
}
What Iam trying to do is
Create a table "table2" with one column "newcol".
select all the values of "col1" from "table1" And
for each value of col1 from table1
-insert the value into "newcol" of table2 And
-add a column named (value from col1 of table 1) into "table2"
The above code looks very neat and efficient in php , but the problem is it takes some amount of time .So I think its better to convert these into MySQL Stored procedure .Since I'm new to stored procedures , very much confused .Please help me guys.
Of course, I couldn't test it, but it is compiling fine on on my computer.
DELIMITER //
CREATE PROCEDURE `myProcedure` ()
BEGIN
DECLARE _done BOOLEAN DEFAULT FALSE;
DECLARE _myField BIGINT UNSIGNED DEFAULT 0;
/* the cursor here is like your PDOStatement
* it is used to fetch data */
DEClARE _myReader CURSOR FOR
SELECT `col1` FROM `table1`;
/* it is not very elegant, but we need to throw an exception
* to break the loop */
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET _done = TRUE;
DROP TABLE IF EXISTS `table2`;
CREATE TABLE `table2` (
`newcol` BIGINT UNSIGNED PRIMARY KEY
);
/* you open your PDOStatement */
OPEN _myReader;
/* myLoop is like a GOTO*/
myLoop: LOOP
/* $result->fetch_array(MYSQL_ASSOC)*/
FETCH _myReader INTO _myField;
/* if the no data exception had been thrown,
* goto the end of the loop */
IF _done = 1 THEN
LEAVE myLoop;
END IF;
INSERT INTO `table2` (newcol) VALUES (_myField);
ALTER TABLE `table2` ADD `_myField` BIGINT DEFAULT 0;
END LOOP myLoop;
/* close your PDO object */
CLOSE _myReader;
END //
Jonathan Parent Lévesque helped me a lot in figuring out how the looping inside stored procedures work and to get the overall structure for the stored procedure equivalent to the php code described in the question above.
Thanks Jonathan Parent Lévesque
But in his code Adding column name using a variable didn't work as expected.
Finally I figured it out
BEGIN
DECLARE _done BOOLEAN DEFAULT FALSE;
DECLARE _myField BIGINT DEFAULT 0;
DEClARE _myReader CURSOR FOR
SELECT id FROM `tags`;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET _done = TRUE;
DROP TABLE IF EXISTS `tag_similarity`;
CREATE TABLE `tag_similarity` (
`tag` BIGINT UNSIGNED PRIMARY KEY
);
OPEN _myReader;
myLoop: LOOP
FETCH _myReader INTO _myField;
IF _done = 1 THEN
LEAVE myLoop;
END IF;
INSERT INTO `tag_similarity` (tag) VALUES (_myField);
SET #sql = CONCAT('ALTER TABLE tag_similarity ADD `',_myfield,'` BIGINT DEFAULT 0');
PREPARE stmt FROM #sql;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
END LOOP myLoop;
CLOSE _myReader;
END
Is there any way in mysql with witch I can take the results of the first query as parameter for the second query in the same procedure?
Yes you can you just need to declare the variable and set the value according to the result of your first query:
DELIMITER //
CREATE PROCEDURE myProc()
BEGIN
DECLARE productname VARCHAR(100);
SET productname = (SELECT product FROM products WHERE product_id = 1);
SELECT * FROM otherproducttable WHERE product = productname;
END //
DELIMITER ;
or
DELIMITER //
CREATE PROCEDURE myProc()
BEGIN
DECLARE productname VARCHAR(100);
SELECT product INTO productname FROM products WHERE product_id = 1;
SELECT * FROM otherproducttable WHERE product = productname;
END //
DELIMITER ;
I have a procedure called SELECT_DESCRIPTION that receives an id and returns a Description field I need to show in my page.
Now I want to create a new procedure that having a number of ids coming from a select clause like this:
SELECT id FROM MYTABLE
Can pass it to the SELECT_DESCRIPTION procedure so I can have the same number of descriptions
If I was using php I would be doing something like this:
$sql=”SELECT id FROM MYTABLE”;
$result = mysql_query($sql) //using mysql to make the example faster but TSQL is what I use
or die(mysql_error());
while($row = mysql_fetch_array( $result )) {
$newSql = "EXEC SELECT_DESCRIPTION #id = '$row[‘id’]'";
//do whatever with $newSql
}
But I need to use a procedure. Is is possible to do it? How can I do it?
Thanks a ton!
So you're wanting to do all of this in TSQL? Something like this would do it:
DECLARE #tmp TABLE (tmpID INT IDENTITY, tblID INT)
DECLARE #RecordCount INT,
#LoopCount INT,
#ID INT
INSERT INTO #tmp SELECT id FROM MYTABLE
SELECT #RecordCount = COUNT(*) FROM #tmp
SET #LoopCount = 1
WHILE #LoopCount <= #RecordCount
BEGIN
SELECT #ID = tblID FROM #tmp WHERE tmpID = #LoopCount
EXEC SELECT_DESCRIPTION #ID
SELECT #LoopCount = #LoopCount + 1
END
The #tmp table has an identity column that insures whatever data you're running the loop on has consecutive row numbers (1, 2, 3, 4, etc).
I have the following stored procedure:
proc_main:begin
declare done tinyint unsigned default 0;
declare dpth smallint unsigned default 0;
create temporary table hier(
AGTREFERRER int unsigned,
AGTNO int unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier values (p_agent_id, p_agent_id, dpth);
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while done <> 1 do
if exists( select 1 from agents a inner join hier on a.AGTREFERRER = hier.AGTNO and hier.depth = dpth) then
insert into hier
select a.AGTREFERRER, a.AGTNO, dpth + 1 from agents a
inner join tmp on a.AGTREFERRER = tmp.AGTNO and tmp.depth = dpth;
set dpth = dpth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = dpth;
else
set done = 1;
end if;
end while;
select
a.AGTNO,
a.AGTLNAME as agent_name,
if(a.AGTNO = b.AGTNO, null, b.AGTNO) as AGTREFERRER,
if(a.AGTNO = b.AGTNO, null, b.AGTLNAME) as parent_agent_name,
hier.depth,
a.AGTCOMMLVL
from
hier
inner join agents a on hier.AGTNO = a.AGTNO
inner join agents b on hier.AGTREFERRER = b.AGTNO
order by
-- dont want to sort by depth but by commission instead - i think ??
-- hier.depth, hier.agent_id;
a.AGTCOMMLVL desc;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end proc_main
While the function does its job well - it only currently allows sorting via AGTCOMMLVL descending order. The stored procedure's purpose is to match a memberID with their parentID and associated COMMLVL. Once paired appropriately,I use the memberID in a second query to return information about that particular member.
I would like to be able to sort by any number of filters but have the following problems:
I can't seem to find a way to pass a variable into the stored procedure altering its sorting by field.
Even if I could - the sort may actually only contain data from the second query (such as first name, last name, etc)
Running a sort in the second query does nothing even though syntax is correct - it always falls back to the stored procedure's sort.
any ideas?
EDIT
My php uses mysqli with code:
$sql = sprintf("call agent_hier2(%d)", $agtid);
$resulta = $mysqli->query($sql, MYSQLI_STORE_RESULT) or exit(mysqli_error($mysqli));
If you want to sort by input parameter of the stored procedure, you need to use Prepared staments
For example,
DELIMITER //
CREATE PROCEDURE `test1`(IN field_name VARCHAR(40) )
BEGIN
SET #qr = CONCAT ("SELECT * FROM table_name ORDER BY ", field_name);
PREPARE stmt FROM #qr;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $value\n";
This also works in Mysql 5.6
DELIMITER //
CREATE PROCEDURE `test1`(IN field_name VARCHAR(40) )
BEGIN
"SELECT * FROM table_name ORDER BY ", field_name);
END //