I have to add some enum options to a database table. The problem being, I will have to do this to several tables & databases, and they may not all have the same enum data type. Is there a why to write an alter table query or something similar to append options to a enum data type?
If there is no way to do this purely in MySQL, how would you approach this problem with a PHP script?
there is not easy way to append enum values.
this is ugly and untested, but i think it will give you an idea:
<?php
$sql = "select table_schema
, table_name
, column_name
, column_type
, is_nullable
, column_default
from information_schema
where data_type = 'enum'";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res)) {
// these are important --> leading comma --v close paren --v
$new_enum = substr($row['column_type', 0, -1) . ",'new','enums','here')"
$sql = "alter table `{$row['table_schema']}`.`{$row['table_name']}`";
$sql .= " modify column `{$row['column_name']}`";
$sql .= " $new_enum";
$sql .= ($row['is_nullable'] == 'YES') ? " NULL" : " NOT NULL";
$sql .= " default $row['column_default']";
mysql_query($sql);
}
you could probably do this "purely in mysql" with a stored procedure, but that's more than i can wrap my brain around right now. :)
Related
I have this php code to do a query foreach loop going through the table name in variable $rowA but I got an "Array to string conversion" error. Does anyone know why? Can we do a query loop this way?
$sql = "SELECT `id`, `first_name` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
$sql_email = "SELECT `email` FROM `clients` ORDER BY `id` DESC";
$account = $DB_CON_C->query($sql_email);
foreach($result as $row) {
foreach($account as $rowA) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$rowA."`";
$amount = $DB_CON_C->query($stmt);
$sum = $amount->total_amount;
$data_row .= '<tr>'
. '<td>' .$row['id'].'</td>'
. '<td>' .$row['first_name'].'</td>'
. '<td>' .$sum.'</td>';
}
}
}
$data_row .= '</tbody>'
. '</table>';
echo $data_row;
There seems to be a fundamentally odd issue with the way you are handling your data values.
Take your first query, $result, this will (obviously depending on the exact $DB_CON_C class method) output an array of values for id and first_name
Yet on the second call, $account using the same method you are then calling the values as if they're class variables $amount->total_amount.
I would suspect that one of these syntax is wrong, but without seeing your class I can't say which.
Do you realise that your two SQL calls are both returning the whole database?
Do you realise that you're using the data value (email address) in one table as the column name in another table? This can work, but this really isn't best practise.
You do not need to use the concaenator . for strings over new lines.
$string = "Hello
this string works fine";
as white space is reduced to one character length in HTML so it doesn't matter (much).
Solving your issue:
var_dump($account) once the value has been populated, same with $results, do var_dump($results) and see what is in the value, if these are class variables or arrays of data?
Seeing that both your variables are calling different parts of the same table, I have rewritten your code below:
$sql = "SELECT `id`, `first_name`, `email` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
/***
* $result is assumed to be an array, within which is a set of values such as:
* $result[0]['id']
* $result[0]['first_name']
* $result[0]['email']
* $result[1]['id'], etc.
***/
foreach($result as $row) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$row['email']."`";
$amount = $DB_CON_C->query($stmt);
/***
* this is inconsistent, your data structure must be like $result as it
* uses the same methods, therefore you will need to enter the first
* "row" before getting the 'total_amount' value
***/
$sum = $amount[0]['total_amount'];
$data_row .= '<tr>
<td>' .$row['id'].'</td>
<td>' .$row['first_name'].'</td>
<td>' .$sum.'</td>
</tr>'; //you forgot your /tr !!
}
// Always clean up after foreach loops.
unset($row);
$data_row .= '</tbody>
</table>';
echo $data_row;
You're trying to parse a database row to a string, even though it contains only one thing.
Change the following line
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA."`";
to
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA['email']."`";
$rowA is a database row and contains the email field from the database.
I want to take the column names from a table and display them, so i can compare them later.
To get the names, i tried:
$entry = mysqli_query($con, 'SHOW COLUMNS FROM table');
and
$entry = mysqli_query($con, "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '$db' AND TABLE_NAME = 'table'");
I don't know whether this runs correctly or not, since i don't get an error message there.
If i try to print the contents of $entry via echo, i keep getting errors.
Previously in my code, i print other entries using:
$test = mysqli_query($con, 'SELECT DISTINCT LK_Release FROM table');
while($row = mysqli_fetch_object($test))
{
echo "Releasename: " . "$row->LK_Release". "<br>";
... }
This output works for me.
What i tried to output the columnnames:
while($row = mysqli_fetch_object($entry))
{
echo $row;
}
Any ideas?
Your query is already correct. But you lack something in the fetching:
while($row = mysqli_fetch_object($entry))
{
echo $row->Field . '<br/>';
// ^ access the objects properties
}
The following SQL statements are nearly equivalent:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
You can use DESCRIBE:
DESCRIBE my_table;
Or in newer versions you can use INFORMATION_SCHEMA:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'my_database' AND TABLE_NAME = 'my_table';
Or you can use SHOW COLUMNS:
SHOW COLUMNS FROM my_table;
I want to change my field comment using php but there is a problem!!
I need to get other column`s features :|
this is my code(gets all column features):
$query = "
SELECT
*
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = '$dbName' AND
TABLE_NAME = '$tableName' AND
COLUMN_NAME = '".$row->name."'";
$result = mysql_query($query) or die($query.'<br>'.mysql_error());
$tempRow = mysql_fetch_object($result);
this is my code that changes the comment
$query = "ALTER TABLE `$tableName`
MODIFY `".$row->name."`
".$tempRow->COLUMN_TYPE."
DEFAULT ".$tempRow->COLUMN_DEFAULT."
COMMENT '$comment'" ;
$result = mysql_query($query) or die($query.'<br>'.mysql_error());
but problem is that i lose some features , for example , outo increament , primary key ...
is there any way that i dont need to write all features , just change comment like update query ?!! if not how I should correct this query?!
Sorry about that, but there is no way to just change a single feature. You always have to specify all features that the column has. So extend your query to reflect all the column's features. All you need for that should be in $tempRow.
if ($tempRow->IS_NULLABLE == "NO")
{
$nullStr =" Not null ";
}else
{
$nullStr =" null ";
}
if (strlen($tempRow->COLUMN_DEFAULT) >0 )
{
$defaultStr = "DEFAULT ".$tempRow->COLUMN_DEFAULT;
}else
{
$defaultStr =" ";
}
if (strlen($tempRow->COLLATION_NAME )>0)
{
$collateStr = "collate " . $tempRow->COLLATION_NAME ;
}
$comment .= implode("|",$info);
$query = "ALTER TABLE `$tableName`
MODIFY `".$row->name."`
".$tempRow->COLUMN_TYPE."
".$nullStr."
".$extraStr."
".$defaultStr."
". $tempRow->EXTRA."
". $collateStr."
COMMENT '$comment'" ;
I have this query: SHOW COLUMNS FROM mash which works fine in my while loop for building a select element made from table column names. But in my table i have "id" and "tstamp" which i dont want in the select element, is this possible to exclude these columns?
echo "<form action='".$_SERVER['PHP_SELF']."' method='get'>";
connectDB();
$result = mysql_query("SHOW COLUMNS FROM mash") or die(mysql_error());
echo '<select name="column" class="column">';
while ($row = mysql_fetch_array($result)) {
echo "<option value='".$row[0]."'>".ucwords($row[0])."</option>";
}
closeConn();
echo '</select>';
echo "</form>";
PHP Way:
Use a continue in the while loop, when those fields are fetched, like this:
echo "<form action='".$_SERVER['PHP_SELF']."' method='get'>";
connectDB();
$result = mysql_query("SHOW COLUMNS FROM mash") or die(mysql_error());
echo '<select name="column" class="column">';
while ($row = mysql_fetch_array($result))
{
if($row[0] == 'id' || $row[0] == 'tstamp')
continue;
echo "<option value='".$row[0]."'>".ucwords($row[0])."</option>";
}
closeConn();
echo '</select>';
echo "</form>";
This will just skip the id and tstamp fields and process all others. continue is used within looping structures to skip the rest of the current loop iteration and continue execution at the condition evaluation and then the beginning of the next iteration.
MySQL Way:
Remove those fields in the query like this:
SHOW COLUMNS FROM mash WHERE Field NOT IN ('id', 'tstamp');
Yes, it's possible. Instead of using SHOW COLUMNS use INFORMATION_SCHEMA.
INFORMATION_SCHEMA is the ANSI way of extracting metadata from a relational database. In MySQL you can use:
$sql = "select column_name from information_schema.columns c " +
" where c.table_schema = 'db_name' " +
" and c.table_name='table_name' " +
" and c.column_name like 'name%'";
Information Schema has the advantage that is SQLANSI compliant. You can use it in MySQL, PostgreSQL, SQLServer and other relational databases.
You can use LIKE operator.
SHOW COLUMNS FROM mash LIKE "name%"
To see just the "Collation" column that shows up in SHOW FULL COLUMNS from tablename for just one field, it's:
select COLLATION_NAME from information_schema.columns
where TABLE_SCHEMA = 'tableschemaname' and TABLE_NAME = 'tablename' and COLUMN_NAME = 'fieldname';
Ddrop the fieldname in the where, if you want to see that column for all field names.
To see all possible column names that show up from SHOW FULL COLUMNS so that you can select what you want:
select * from information_schema.columns
where TABLE_SCHEMA = 'tableschemaname' and TABLE_NAME = 'tablename' and COLUMN_NAME = 'fieldname';
What is the best way to check if a table exists in MySQL (preferably via PDO in PHP) without throwing an exception. I do not feel like parsing the results of "SHOW TABLES LIKE" et cetera. There must be some sort of boolean query?
Querying the information_schema database using prepared statement looks like the most reliable and secure solution.
$sql = "SELECT 1 FROM information_schema.tables
WHERE table_schema = database() AND table_name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$tableName]);
$exists = (bool)$stmt->fetchColumn();
If you're using MySQL 5.0 and later, you could try:
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '[database name]'
AND table_name = '[table name]';
Any results indicate the table exists.
From: http://www.electrictoolbox.com/check-if-mysql-table-exists/
Using mysqli I've created following function. Assuming you have an mysqli instance called $con.
function table_exist($con, $table){
$table = $con->real_escape_string($table);
$sql = "show tables like '".$table."'";
$res = $con->query($sql);
return ($res->num_rows > 0);
}
Hope it helps.
Warning: as sugested by #jcaron this function could be vulnerable to sqlinjection attacs, so make sure your $table var is clean or even better use parameterised queries.
This is posted simply if anyone comes looking for this question. Even though its been answered a bit. Some of the replies make it more complex than it needed to be.
For mysql* I used :
if (mysqli_num_rows(
mysqli_query(
$con,"SHOW TABLES LIKE '" . $table . "'")
) > 0
or die ("No table set")
){
In PDO I used:
if ($con->query(
"SHOW TABLES LIKE '" . $table . "'"
)->rowCount() > 0
or die("No table set")
){
With this I just push the else condition into or. And for my needs I only simply need die. Though you can set or to other things. Some might prefer the if/ else if/else. Which is then to remove or and then supply if/else if/else.
Here is the my solution that I prefer when using stored procedures. Custom mysql function for check the table exists in current database.
delimiter $$
CREATE FUNCTION TABLE_EXISTS(_table_name VARCHAR(45))
RETURNS BOOLEAN
DETERMINISTIC READS SQL DATA
BEGIN
DECLARE _exists TINYINT(1) DEFAULT 0;
SELECT COUNT(*) INTO _exists
FROM information_schema.tables
WHERE table_schema = DATABASE()
AND table_name = _table_name;
RETURN _exists;
END$$
SELECT TABLE_EXISTS('you_table_name') as _exists
As a "Show tables" might be slow on larger databases, I recommend using "DESCRIBE " and check if you get true/false as a result
$tableExists = mysqli_query("DESCRIBE `myTable`");
$q = "SHOW TABLES";
$res = mysql_query($q, $con);
if ($res)
while ( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
{
foreach( $row as $key => $value )
{
if ( $value = BTABLE ) // BTABLE IS A DEFINED NAME OF TABLE
echo "exist";
else
echo "not exist";
}
}
Zend framework
public function verifyTablesExists($tablesName)
{
$db = $this->getDefaultAdapter();
$config_db = $db->getConfig();
$sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{$config_db['dbname']}' AND table_name = '{$tablesName}'";
$result = $db->fetchRow($sql);
return $result;
}
If the reason for wanting to do this is is conditional table creation, then 'CREATE TABLE IF NOT EXISTS' seems ideal for the job. Until I discovered this, I used the 'DESCRIBE' method above. More info here: MySQL "CREATE TABLE IF NOT EXISTS" -> Error 1050
Why you make it so hard to understand?
function table_exist($table){
$pTableExist = mysql_query("show tables like '".$table."'");
if ($rTableExist = mysql_fetch_array($pTableExist)) {
return "Yes";
}else{
return "No";
}
}