I'd like to make a table with row entries that define columns in another Table. This way I can easily update the tables later on if the questions for a form are changed or added.
Eg.
Table1: Questions
Question column_name column_type characters default
What is your name? name Char 255 ''
When where you born? birth char 255 ''
What is today's date? date int ''
Do you have a pet? pet bin 0
Table2: Results
name birth date
Cammy Teaneck 1988
Tommy Tenefly 2001
Tasha Brooklyn 1950
In the php form, check to see if all columns exist, if not create them in table2 and then add entry
$collect = db_query("SELECT column_name FROM {Table1}");
while ($data = db_fetch_array($collect)){
$name = $data['column_name'];
$stretch = db_query("SELECT $name FROM {Table2}");
if ($stretch == null or false){
UPDATE TABLE Table2 ($name $type($char) DEFAULT $default)
}
}
The pseudocode for what you are asking for is as follows:
foreach column in table1 {
$res = query("select column from table2");
if( ! $res ) {
query("alter table add field datatype(size) to table 2");
}
}
Heres a crude implementation, from where I got the idea from:
http://forums.phpfreaks.com/topic/193330-alter-table-add-column-if-not-exists-possible/
Please use information schema in mysql to check
whether this table contain this field or not
you can Find table name in information_schema this
use Like this
SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME='Table2' and COLUMN_name IN ('name','birth','date')
Please try this
Related
I have a dynamic table named 'products' with multiple Languages.
The table columns looks like this:
id, product_id, store_de, store_en, store_fr, store_es... etc
The languages can be more or less.
Now I want to update this table and set all columns beginning with "store_" to value 1.
I tried the following:
$stmt = $dbh->prepare( "UPDATE products SET `store_%` = ? WHERE product_id = ?" );
$stmt->execute( array( 1, $lastID ) );
I get following error message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'store%' in
'field list'
Is there a way to update all columns beginning with 'store_' or do I have to list all the columns?
Based on the answer from jekaby here is the full solution that worked for me:
$get_stores = $dbh->prepare("SHOW COLUMNS FROM products_active WHERE field REGEXP '^store'");
$get_stores->execute();
$stores = $get_stores->fetchAll();
$update_string = "";
$first_store = true;
foreach($stores as $store) {
if(!$first_store) {
$update_string .= ", ";
} else {
$first_store = false;
}
$update_string .= $store['Field']." = '".$status."'";
}
$update_activity = $dbh->prepare("UPDATE products_active SET $update_string WHERE product_id = ?");
$update_activity->execute(array($product_id));
You need to set each column explicitly. SQL doesn't support wildcards for column names (with the exception of * for SELECT *):
update products
set store_de = 1,
store_en = 1,
store_fr = 1,
store_es = 1,
. . .
where product_id = ?;
Your data structure suggests that you really want a ProductStores table. This would have one row per language (?) and per product. It would have at least three columns:
ProductId
Language
Value
Then you would simply do:
update ProductStores
set Value = 1
where ProductId = ?;
You can not do like this store_% - it is nonexistent column in table as it is written in your error.
You should get all colums with names like /^store_/ (regexp). And than update all this fields having listed them.
mysql> SHOW COLUMNS FROM products where field REGEXP '^store_'
Than collect all fields from 'Field'... You can read more how to get all columns here.
I have some table in my SQLite3 database , for example
table1
table2
table3
All tables have a field called id (integer NOT NULL PRIMARY KEY UNIQUE) (not auto increment)
My goal is to duplicate a record of one of these tables, changing only the id field (with a new id). I would like to do this without having to know the name of all the columns in each table.
I tried this solution, it works, but in this way i have to know the names of all columns
INSERT INTO table1 (id,column1,column2,column3)
SELECT NEWID,column1,column2,column3 FROM table1
WHERE id = OLDID
I tried also the method to create a temporary table, but without success
I have to run a query like this PRAGMA table_info(table1) , save the columns's name in an array , and then run a query created with a cycle ?
thanks
My solution
$TABLENAME = "mytablename";
$ID = 1423659222480;
$NEWID = 1423659222481;
$db = new PDO('sqlite:db.sqlite3');
$result_columns = $db->query("PRAGMA table_info(".$TABLENAME.")");
$appColumns = array();
$appColumns2 = array();
foreach ($result_columns as $row) {
array_push($appColumns, $row["name"]);
if($row["name"] != "id") array_push($appColumns2, $row["name"]);
}
$appColumns = implode(",",$appColumns);
$appColumns2 = implode(",",$appColumns2);
$appColumnsWithoutID = $NEWID.",".$appColumns2;
$queryDuplicate = "INSERT INTO ".$TABLENAME." (".$appColumns.") SELECT ".$appColumnsWithoutID." FROM ".$TABLENAME." WHERE id = ".$ID;
How can i get the auto increment field name using ALTER TABLE
Or
Is there any other idea to get auto increment field
You can get table details something like this
$res = $mysqli->query('SHOW COLUMNS FROM tablename');
while($row = $res->fetch_assoc()) {
if ($row['Extra'] == 'auto_increment')
echo 'Field with auto_increment = '.$row['Field'];
if ($row['Key'] == 'PRI')
echo 'Field with primary key = '.$row['Field'];
}
You can use information_schema database for that
SELECT column_name, column_key, extra
FROM information_schema.columns
WHERE table_schema = 'yourdatabase'
AND table_name = 'yourtable'
AND extra = 'auto_increment'
If you look in the information_schema database you can find the auto increment value for a table in the TABLES table. The COLUMNS table contains details of each column, and the extra field on this table will show auto_increment for auto incrementing columns.
is there a way to get default values of columns as they are a row of a resultset?
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`state` tinyint(2) NOT NULL DEFAULT '22',
`pubdate` datetime NOT NULL DEFAULT '2012-01-01 00:00:00',
for instance a table like this should return this record:
id->NULL (?)
state->22
pubdate->2012-01-01 00:00:00
in practice, when some user opens edit.php?id=44 he will get the row 44 (update mode), but if he opens edit.php?id=0 (insert mode) I want that the fields contain default values as place holders
thank you in advance
There is a DEFAULT function
SELECT DEFAULT( id ) , DEFAULT( EXAMPLE ) FROM test LIMIT 1
With above query, it seems that you need to have atleast one record in the table as it returns no records otherwise. For current timestamp, it return a timestamp formatted string of 0s.
Sure, using the information_schema database (which stores all the information about your database structure), you can do something like:
SELECT
COLUMN_NAME,
COLUMN_DEFAULT
TABLE_NAME
FROM information_schema.COLUMNS
WHERE
TABLE_NAME='your_table_name'
AND TABLE_SCHEMA='your_database_name'
If you have a limited number of columns, you can collect them into a row using a construct like:
SELECT
id.defaultval AS id_default,
state.defaultval AS state_default,
pubdate.defaultval AS pubdate_default
FROM
(SELECT TABLE_NAME, COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='id') id
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='state') state ON id.TABLE_NAME = state.TABLE_NAME
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='pubdate') pubdate ON id.TABLE_NAME = pubdate.TABLE_NAME
Use DESCRIBE http://dev.mysql.com/doc/refman/5.0/en/describe.html
DESCRIBE sometable [somefield]
Here is php example for single field:
$resource = mysql_query("DESCRIBE sometable somefield");
$schema = mysql_fetch_assoc($resource);
$default = $schema['default'];
And here is the php example for few fields:
$resource = mysql_query("DESCRIBE sometable");
while ($schema = mysql_fetch_assoc($resource)) {
$default_list[$schema['Field']] = $schema['Default'];
}
I see no use for such a behavior and find it wrong.
It is not convenient to use. Imagine I want to enter my own state value. I'd have to delete default 22 first.
Even worse with date. Instead of setting current datetime, you are going to make me edit whole date. Why?
And for the id it is just impossible.
Why can't you just check the input fields and if empty - not to insert at all, letting database set these defaults
You just overthinked it, I believe.
I have my database with table test1.
It has a primary id "Id" which is auto-increment.
Now the id is in the format 1,2,3.. . .Is it possible to store the primary Id as
PNR1,PNR2,PNR3 .. . . and so on(with auto-increment).
No. Either add the prefix in the query, or use a view instead.
Not really, but you can use another column (but a view)
this is already covered here:
MySQL Auto Increment Custom Values
Yes you can do it if you have INT prefix. You have id as INT in table
// START PREFIX
$query = mysql_query("SELECT id FROM `table_name` ORDER BY id DESC LIMIT 1");
// GET THE LAST ID MAKE SURE IN TABLE YOU 9991
while ($row = mysql_fetch_object($query)) {
$lastId = $row->id;
}
list($prefix,$Id) = explode('999',$lastId );
$Id = ($Id+1);
$new_id = '999'.$Id;
// END PREFIX
$insertQuery = mysql_query("INSERT INTO `table_name` SET id = '".$new_id."',...");
Hi, I made it work in this way :
Products Table (products):
id_prod(varchar(11), NOT NULL, PK), name(varchar(40))
Products Sequence Table (productidseq):
id(AI, PK, NOT NULL)
Before Insert Trigger in Products Table:
CREATE DEFINER=`root`#`localhost` TRIGGER `dbname`.`products_BEFORE_INSERT` BEFORE INSERT ON `products` FOR EACH ROW
BEGIN
insert into productidseq (id) values(NULL);
set new.id_prod = concat('PROD or any prefix here',last_insert_id());
set #productId = new.id_prod; -- To use outside of trigger this variable is useful.
END
When you run below query :
insert into products (name) values('Bat');
data inside tables will we be like this :
products:
id | name
---|-----
1 | Bat
productidseq:
id
---
1
If any better way than this or any cons with this, please comment below. Thanks.