Use prepared statement into creating temporary table - php

I have been trying to change existing table and insert the result into temporary table with memoery engine
1) Step - I swaped rows and columns from existing table
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(`parameterId` = ', `parameterId`, ',`valueId`,NULL)) AS parameter', `parameterId`)
) INTO #sql
FROM product_parameter;
SET #sql = CONCAT('SELECT productId , ', #sql , ' FROM product_parameter GROUP BY productId');
PREPARE stmt FROM #sql;
When I execute the stmt statement it will show me a the result
2) Step - I would like to insert the result to temporary table or for testing into physical table
CREATE TEMPORARY TABLE IF NOT EXISTS temporaryTable ENGINE=MEMORY AS
Is it possible to acomplish my goal by one query? Or should i create table then somehow add the result data?

You should create the temporary table and the populate it.

Related

Mysql generated always as column multiply variable

SELECT #a:= deger1 FROM iscilik1 WHERE Id=16;
ALTER TABLE iscilik1kisiler MODIFY COLUMN deger4 DECIMAL GENERATED ALWAYS AS (#a*deger3) STORED;
Hi everyone.I have a problem with this code and giving error like this;enter image description here
I could not find where is the problem.Thanks for everything have a good jobs.
SELECT CONCAT( 'ALTER TABLE iscilik1kisiler ',
'MODIFY COLUMN deger4 DECIMAL ',
'GENERATED ALWAYS AS (',
deger1,
'*deger3) STORED' )
INTO #sql
FROM iscilik1
WHERE Id=16;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;

Use inserted id for another column value

I have an identity column (id) that auto-increments.
id|name|image_path
I want to know if there is some way using mysql, to use the newly inserted id in the image_path.
For example if a new row is inserted and got the id 2 I want the image_path to be "/images/2.png".
Or do I have to use the traditional way, by inserting and then fetching this ID then updating the entry?
My opinion is that it is impossible to do with one query. You won't know new autoincrement value until row will be inserted. Still you can write 1 query to achieve what you want (actually 2 queries would be executed):
insert into `t`(`id`, `name`, `image_path`)
values(
(SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES
WHERE `table_name` = 't'),
'1234',
concat(
'/images/',
(SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES
WHERE `table_name` = 't'),
'.png'
)
)
Anyway much safer would be:
START TRANSACTION;
set #c = (select ifnull(max(`id`),0) + 1 from `t`);
insert into `t`(`id`, `name`, `image_path`) values (#c,'123',concat('/images/',#c,'.png'));
COMMIT;
Yes, it is possible with oracle. We have dynamic sql feature.
have tried the below.
Created a sequence and then created a procedure which takes id as input and creates an insert statement dynamically which will fulfill your requirement.
create sequence seq1 start with 1;
create table image1(id1 number,image varchar2(50));
create or replace procedure image1_insert(id1 in number)
as
sql_stmt varchar2(50);
image_path varchar2(50);
begin
sql_stmt:='insert into image1 values(:1,:2)';
image_path:='/image/'||id1||'.png';
execute immediate sql_stmt using id1,image_path;
end;
begin
image1_insert(seq1.nextval);
end;
id image
4 /image/4.png
5 /image/5.png
select *from image1;

PHP MySQL Pivot Table Code

I've written this code for mysql pivot table:
SET #SQL = NULL;
SET ##group_concat_max_len = 6000;
SELECT GROUP_CONCAT( DISTINCT CONCAT( 'MAX(IF(questiondetails = \'', questiondetails, '\', answer, null)) AS \'', questiondetails, '\' ' )) INTO #SQL FROM wtfeedback;
SET #SQL = CONCAT( 'SELECT trialid, productsku, userkey, category, ', #SQL, ' FROM wtfeedback GROUP BY trialid' );
PREPARE stmt FROM #SQL;
EXECUTE stmt;
This works fine in Sequel Pro (mysql gui editor)
But when I paste into my php page to run this code it is showing a syntax error:
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 'SET ##group_concat_max_len = 6000;
SELECT GROUP_CONCAT( DISTINCT CONCAT( 'MAX(I' at line 3
I'm struggling to see what the error might be.
Any ideas ? Thanks in advance.
MySQL doesn't use '' to escape single quotes. If you want to embed single quotes in your in-sql strings, then use \':
CONCAT('MAX(IF(questiondetails = \'', questiondetails, '\', answer, null)) AS "', questiondetails, '" ')
^^---------------------^^
From PHP, issue only one statement at a time. I deduce that this is the problem since the error is pointing at the beginning of the second SET.
Here is a stored proc to generate a pivot SELECT for you.
I was struggling with the same issue as Guy Murray, but fought my way out.
Basically I made a stored procedure that lets you run a pivot table on selectable rows and columns, with optional filtering. It does so by first storing the result of a "group by" select query in a temp table, and then fiddling that to a pivot table with the "group_concat" function. Same trick as Guy does.
The advantage is that it goes through the main table only once, which may save time if there are zillions of records in it.
Here is a sample table:
CREATE TABLE `Data` (
`Period` INT(2) NOT NULL,
`Product` VARCHAR(20) NOT NULL DEFAULT '',
`Amount` DOUBLE NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1;
INSERT INTO `Data` (`Period`, `Product`, `Amount`)
VALUES
(1,'PrdA',15484),
(1,'PrdA',45454),
(1,'PrdB',478),
(2,'PrdB',985),
(2,'PrdB',741),
(2,'PrdB',985),
(3,'PrdA',7515),
(3,'PrdA',454),
(3,'PrdB',4584),
(2,'PrdB',445),
(1,'PrdB',669);
And this is the stored procedure. Additional comment in the code.
DELIMITER ;;
CREATE DEFINER=`root`#`localhost` PROCEDURE `pivot`(
source VARCHAR(1000),
val VARCHAR(40),
rws VARCHAR(40),
cls VARCHAR(40),
filter VARCHAR(1000))
BEGIN
/*
Creates a pivot table from any table, view or SQL statement.
Mandatory: source, value, rows, and columns to be pivoted.
Optional filtering.
Sample call strings:
CALL pivot('data', 'amount', 'period', 'product', '');
CALL pivot('(select * from data)', 'amount', 'product', 'period', 'WHERE amount>1000');
*/
/*just to be sure*/
DROP TEMPORARY TABLE IF EXISTS temp1;
/*increase the value of group concat, otherwise the number of columns is very limited*/
SET SESSION group_concat_max_len = 100000;
/*perform a "select...group by" on the source and store it in a temp table1*/
SET #a=CONCAT(
'CREATE TEMPORARY TABLE temp1 (
SELECT ',
rws,' AS rows, ',
cls,' AS cols,
SUM(',val,') AS val
FROM ',source,' S ',
filter, '
GROUP BY '
,rws,', ',
cls,');'
);
PREPARE stmt FROM #a;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
/*use "distinct columns" from temp1 to make a text string #coltext, that contains the column statements, to be used in the final step
Produced text string looks like this: sum(CASE WHEN cols='PrdA' THEN val END) AS 'PrdA', sum(CASE WHEN cols='PrdB' THEN val END) AS 'PrdB' */
SELECT GROUP_CONCAT(
' SUM(CASE WHEN cols=\'',cols,'\' THEN val END) AS \'',cols,'\'')
INTO #coltext
FROM (SELECT DISTINCT(cols) AS cols FROM temp1) A;
/*build the final statement in #b*/
SET #b=CONCAT(
'SELECT
IFNULL(rows, \'Total\') AS ',rws,', '
,#coltext,',
SUM(val) AS Total
FROM temp1
GROUP BY
rows
WITH ROLLUP;');
/*and launch it*/
PREPARE stmt FROM #b;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
/*clean up*/
DROP TEMPORARY TABLE IF EXISTS temp1;
SET #a=NULL;
SET #b=NULL;
SET #coltext=NULL;
END;;
DELIMITER ;
The result looks like this:
period PrdA PrdB total
1 60938 1147 62085
2 NULL 3156 3156
3 7969 4584 12553
total 68907 8887 77794
Hope this shows up correctly on stack overflow. It's my first post here.
edit 2015-10-19: when reading others solutions here, I realised that the code could be cleaned up and improved: it's now free of any hardcoded references. Just plug it in any database and it will work.

bulk changing column types in MySQL

I have a PHP script where users create questionnaires, and the script tables in the DB to store the incoming data. The site's been live for a while, and there are about 100 tables in the database.
My script was awfully flawed! It calls for "tinytext" fields in places where I really need "text". Is there a way to bulk update all of the tinytext columns to text?
Thanks!
Solution without stored procedures (using only phpMyAdmin or any other DBA tool).
Run the following query
SELECT
CONCAT('ALTER TABLE ',
TABLE_NAME,
' CHANGE COLUMN ',
COLUMN_NAME,
' ',
column_name,
' TARGET_TYPE ',
CASE
WHEN IS_NULLABLE = 'NO' THEN ' NOT '
ELSE ''
END,
' NULL;') AS que
FROM
information_schema.columns
WHERE
table_schema = 'MY DB'
AND data_type = 'SOURCE_TYPE';
This query will return you all the statements to fire. You can run them or save into a SQL Upgrade script
Example (from tinyint to bit):
ALTER TABLE mytable CHANGE COLUMN redacted redacted BIT NULL;
ALTER TABLE mytable CHANGE COLUMN redacted2 redacted2 BIT NOT NULL;
One way of doing this, is to find all the tinytext columns in the given database and then create ALTER TABLE statement for the each column. Working solution using stored procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `BULK_RETYPE` $$
CREATE PROCEDURE `BULK_RETYPE`(IN SCHEMA_NAME VARCHAR(255), IN FROM_TYPE VARCHAR(255), IN TO_TYPE VARCHAR(255))
BEGIN
DECLARE `done` INT DEFAULT FALSE;
DECLARE tn VARCHAR(255);
DECLARE fn VARCHAR(255);
DECLARE `cur1` CURSOR FOR
SELECT
`TABLE_NAME`,
`COLUMN_NAME`
FROM
`information_schema`.`COLUMNS`
WHERE
`DATA_TYPE` = FROM_TYPE AND `TABLE_SCHEMA` = SCHEMA_NAME;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO `tn`, `fn`;
IF done THEN
LEAVE read_loop;
END IF;
SET #ALTER_SQL = CONCAT('ALTER TABLE ', '`', tn,'`' , ' MODIFY ', '`', fn,'`' , ' ', TO_TYPE);
PREPARE stmt1 FROM #ALTER_SQL;
EXECUTE stmt1;
END LOOP;
CLOSE cur1;
END $$
DELIMITER ;
CALL BULK_RETYPE('test', 'tinytext', 'text');
Not really, though if you use PHPMyAdmin, it's a rather quick task... alternatively, you could export a list of all the tables and fields you need to change and put together the necessary ALTER TABLE statements and then execute them.
You can just select from schema and prepare SQL for mass alter
SELECT table_scheme, table_name, columun_name FROM information_schema.`COLUMNS`
WHERE DATA_TYPE='tinyint'

MSSQL dose not return data for all fields

I am trying to run a procedure in which i will send the table name to fetch all records from it..so that i don't have to create different procedure...but i am facing some problem in that.
ALTER PROCEDURE [dbo].[getTableData]
-- Add the parameters for the stored procedure here
#tableName Varchar(100),
#whrFldName NVarchar(100)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #ActualTableName AS NVarchar(255)
SELECT #ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #tableName
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'SELECT * FROM ' + #ActualTableName + ' WHERE ' +
#whrFldName + ' = ''y'' ;'
--PRINT #sql
EXEC(#SQL)
END
The PHP code is this..
$sql ="EXEC [dbo].[getTableData] 'tbl_services','serviceStatus'";
$rst = odbc_exec($connection, $sql);
$i = 0;
while($result = odbc_fetch_array($rst))
{
$returnPageData[$i] = $result;
$i++;
}
It executes just fine in server but when I call it from my PHP code, it returns null.
Here if I remove * and place fields it works fine..I have tested my code well,it specially creates the problem for a Text type field..
If i change the procedure to this,it works fine..
ALTER PROCEDURE [dbo].[getTableData]
-- Add the parameters for the stored procedure here
#rowsPerPage as bigint,
#pageNum as bigint
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
WITH SQLPaging AS (
SELECT TOP(#rowsPerPage * #pageNum) ROW_NUMBER() OVER (ORDER BY creationDate DESC)
AS resultNum, *
FROM [DB_SB].[dbo].[tbl_blog] )
SELECT
blogTitle,
blogSlug,
blogImage,
substring( blogContent, 1, 210 ) AS blogContent,
creationDate,
blogAddedBy
FROM SQLPaging WITH (nolock) WHERE resultNum > ((#pageNum - 1) * #rowsPerPage)
END
But this is no logical..if i send fields everytime..this is not what i want exactly..
Any solution??please help...
You need to use SQL Server Profiler to see what’s actually getting to database engine.
If your stored procedure is executed correctly when run from SSMS then there is a problem somewhere in PHP part.
Are you using the same database using when testing from SSMS? There might be some issue in that…

Categories