Blank variables and INT columns? - php

I have a column in a table which is has the data type of an integer. What I had in mind was that values added into that column will be either 0 - N, or just blank as in an empty variable (see below), but I'm not sure that this is possible?
if($resource) {
$resource = $id - 2;
} else {
$resource = "";
}
$result = mysql_query("INSERT INTO table (...,resource,...) VALUES (...,'$resource',...)");
If not, could I instead use the data type of VARCHAR, and then say:
if($resource) {
$resource = $id - 2;
} else {
$resource = "INVALID";
}
In that case, is there any conversion functions I'd have to do when extracting values from the column resource, or would numbers automatically be treated as integers?

If the field should be "white" for any reason, I think you should mark it as NULLABLE and use word NULL (not INVALID)
If a column is a number, never use a varchar, you will loose a lot of things (also, an int is smaller than a varchar)
EDIT 1: Code snippet to allow null values on column:
ALTER TABLE mytable MODIFY mycolumn INT;
If you specify it as:
ALTER TABLE mytable MODIFY mycolumn INT NOT NULL;
It will be not nullable, so it should be nullable by default if you didn't declare it differently
EDIT 2: Important note, the column must not be UNIQUE otherwise the value will be not nullable!

Related

Get database table columns where DEFAULT value is not set

We recently updated our mariadb version and it is more strict on default column values, meaning if they are not set and not defined on insert it does not insert a new row. I am looking for a quick way to update all of the database columns that do not have a default value.
I imagine the code should look something like this, keep in mind this is only a pseudo code that I imagine and running this is not going to work:
$result = dbquery("SHOW TABLES");
while ($row = dbarray($result))
{
foreach ($row as $key => $table)
{
// this is the query where it should check
// if default value is set or not, but could not find information on how to do so
$result2 = dbquery("SHOW COLUMNS FROM $table WHERE DEFAULT IS NOT SET");
while ($column = dbarray($result2))
{
// SETTING A DEFAULT VALUE
dbquery("ALTER $table ALTER $column SET DEFAULT NULL");
}
}
}
NOTE: DISABLING STRICT MODE IS NOT A SOLUTION THAT I AM LOOKING FOR IN CURRENT TIME
Any ideas on how to select the columns where the default value is not set?
Thanks
Not providing a value for a nullable column is OK, so I suspect that you want to identify non-nullable column that have no default.
You could get that information from information_schema.columns:
select table_name, column_name
from information_schema.columns
where column_default is null and isnullable = 'NO'
From there on, you would need to decide which value should be used as a default; the answer does depends on your actual requirement and of the datatype of the column.

MySQL Where clause values 0 and 1 not working correctly

The situation
In table I have columns configurated as ENUM('0','1'). I have select query build with PDO like this example
$value = isset($_POST['value']) ? $_POST['value'] : (isset($_GET["value"]) ? $_GET["value"] : null);
$sql = $pdo->prepare("SELECT * FROM tablename WHERE column = :value");
$sql->bindValue(':value', $_POST['value']); // post contains 0 or 1
$sql->execute();
The problem
When printing the results, value 1 is working normally. But when using value 0, all rows are showing including rows with value 1.
Following query is working normally when trying it in HeidiSQL, but it's not with PHP. What's wrong? SELECT * FROM tablename WHERE column = '0'
I noticed that PHP thinks $_POST['value'] is unset when its value is zero. I'm using isset()
Trying to solve the problem
No effect either if using $_GET['value'] and url like index.php?value=0
Tried following, not working $sql->bindValue(':value', '0'); // post contains 0 or 1
I changed column type to TINYINT(1) - no effect. When looking for zero, all are showing.
Set PDO bindValue() $data_type to PDO::PARAM_BOOL, not working
Try this:
$value = empty($_POST['value']) ? '0' : '1' ;
$sql = $pdo->prepare("SELECT * FROM tablename WHERE column = :value");
$sql->bindValue(':value', $value, PDO::PARAM_STR); // post contains 0 or 1
$sql->execute();
Good luck!
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table creation time.
An enumeration value must be a quoted string literal; it may not be an expression, even one that evaluates to a string value.
The index value of the empty string error value is 0. This means that
you can use the following SELECT statement to find rows into which
invalid ENUM values were assigned:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
So use single quote to consider the zero(0) as string.

SQL query to alter table column names

I am running this SQL Query in PHP:
$sql="alter table callplandata change '".$_POST["col_name$y"]."' '".$_POST["col_newname$y"]."' ";
to alter column names but before it updates i want to check if the column name already exists and if it does to add a number on the end otherwise to just carry on updating
how can i do this using PHP?
Please, please, please, don't do this. This is about as unsafe a thing to do. However, I will say this: The ALTER TABLE syntax is worth a look:
ALTER TABLE <table name>
CHANGE [COLUMN] old_col_name new_col_name column_definition
Note that the column_definition bit is not optional.
Also, if you want to see if the fieldname given already exists:
SHOW COLUMNS FROM <table_name> /* or SHOW COLUMNS IN tbl */
Then, in PHP, depending on the extension you used, you do something like this:
$existingFields = array();
foreach ($resultSet as $row)
{
$existingFields[] = $row['Field'];
}
SHOW COLUMNS will also give you information concerning the type of each field, if it's a key, or even if it's an auto_increment value details, as ever, on the mysql website
So putting it all together:
$db = new PDO();//connect
$stmt = $db->prepare('SHOW COLUMNS IN callplandata WHERE Field = :field');
$bind = array(
':field' => $_POST['colname_new']
);
$stmt->execute($bind);
if ($row = $stmt->fetch())
throw new InvalidArgumentException($_POST['colname_new'].' already exists!');
$bind[':field'] = $_POST['colname_old'];
$stmt->closeCursor();//reset cursor, so we can re-use the statement
$stmt->execute($bind);//re-use statement
if (!($row = $stmt->fetch(PDO::FETCH_OBJ))
throw new InvalidArgumentException($_POST['colname_old'].' does not exist, cannot rename it!');
//very basic column definition construction here, needs more work, though!
$current = '';
$current = $row->Type. ' '.($row->Null == 'NO' ? 'NOT NULL ' : '').
($row->Default !== '' ? 'DEFAULT '.$row->Default.' ' : '').$row->Extra;
/**
* ADD CODE HERE TO SANITIZE THE NEW COLUMN NAME
* if you want to procede with this madness... I would urge you not to, though!
*/
$pdo->exec(
'ALTER TABLE callplandata
CHANGE '.$_POST['colname_old'].' '.$_POST['colname_new'].' './/rename
$current//add column definition
);
Disclaimer:
The code I posted here is meant to be purely academic. It should not be used, it's unsafe and incomplete. Please rethink what you are trying to do. Avoid, at all cost, using user data to alter how the server stores/structures the data!
Try this
SELECT *
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'db_name'
AND TABLE_NAME = 'table_name'
AND COLUMN_NAME = 'column_name'
In PHP
$result = mysqli_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'");
$exists = (mysqli_num_rows($result))?TRUE:FALSE;
I think you need to specify datatype and default value also.
example
ALTER TABLE `ca_4_4_14` CHANGE `active` `is_active` ENUM('Y','N') CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'Y' NOT NULL;

Stored procedure with variables not working

I call the procedure with php and the relevant variables. I need the latest IDs to use it for the next insert, so I set variables with SCOPE_IDENTITY. The return ist always the value of appointment_id ?!
ALTER proc [dbo].[insertPersonWithCmoFmo]
#appointment_id int,
#kostenstelle varchar(50),
#vorname varchar(50),
#nachname varchar(50),
#ci_nummer int,
#anzahl_monitore_old int,
#raum varchar(50),
#gebäude varchar(50),
#bemerkung text,
#hardware_typ varchar(50),
#anzahl_monitore_new varchar(50),
#zubehör text
as
DECLARE
#latestPersonID int,
#latestCmoID int,
#latestFmoID int
BEGIN
INSERT INTO [RC.Persons] (kostenstelle, vorname, nachname) VALUES (#kostenstelle, #vorname, #nachname);
SET #latestPersonID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.CMO] (ci_nummer, anzahl_monitore, raum, gebäude, bemerkung) values (#ci_nummer, #anzahl_monitore_old, #raum, #gebäude, #bemerkung);
SET #latestCmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.FMO] (hardware_typ, anzahl_monitore, zubehör) values (#hardware_typ, #anzahl_monitore_new, #zubehör);
SET #latestFmoID = (SELECT SCOPE_IDENTITY())
INSERT INTO [RC.Appointments_RC.CMO] (cmo_id, appointment_id) values (#latestCmoID, #appointment_id);
INSERT INTO [RC.Persons_RC.CMO] (cmo_id, person_id) VALUES (#latestCmoID, #latestPersonID);
INSERT INTO [RC.Persons_RC.FMO] (fmo_id, person_id) VALUES (#latestFmoID, #latestPersonID);
return #latestFmoID
END
This is the exec code. Why the is a "N" before all varchar type?
USE [Testtable]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[insertPersonWithCmoFmo]
#appointment_id = 52,
#kostenstelle = N'54',
#vorname = N'testname',
#nachname = N'testlastname',
#ci_nummer = 111222333,
#anzahl_monitore_old = 2,
#raum = N'255',
#gebäude = N'KWA12',
#bemerkung = N'blablabla',
#hardware_typ = N'Desktop',
#anzahl_monitore_new = N'4',
#zubehör = N'Test'
SELECT 'Return Value' = #return_value
GO
SQL Output:
Meldung 2601, Ebene 14, Status 1, Prozedur insertPersonWithCmoFmo, Zeile 36
Cannot insert duplicate key row in object 'dbo.RC.FMO' with unique index 'NonClusteredIndex-20140116-143317'. The duplicate key value is ().
The statement has been terminated.
Is there something about the error message you don't understand? One or more of the tables has a unique constraint (or index) and you are trying to insert the same values in the table. For example, the persons table might already have the person in it.
The N before the string explicitly makes the string use wide characters.
Your stored procedure probably needs to be rewritten. You need to check errors that might occur along the way. Traditionally, a value would be returned using an OUTPUT parameter.
The safest way to get the new id value is to use the output clause of the insert statement (see the documentation here).
The N indicates nvarchar instead of varchar.
See:
https://stackoverflow.com/questions/10025032/what-is-the-meaning-of-the-prefix-n-in-t-sql-statements

Integer inserting as 0 instead of NULL

When I insert a NULL into a MYSQL INTEGER field via a PHP prepared statement it inserts as 0.
I have searched for similar questions and have update my code but am still having the problem.
In my code, if a text box sends an empty string to PHP; PHP converts it to NULL ie.
$v3 = (strlen($v3)<1 ) ? NULL : $v3;
As an example, a result in the UNIT column could be NULL.
The prepare statement
$stmt = $mysqli->prepare("INSERT INTO address ( `PERSON`, `TYPE`, `UNIT`, `STREET_NUM`, `STREET`, `STREET_TYPE`, `SUBURB`, `STATE` ) VALUES (?,?,?,?,?,?,?,?)"));
Bind the parameter as an integer
$stmt->bind_param('isiissss',$p, $add_type[$a], $unit[$a], $street_num[$a], $street_name[$a], $street_type[$a], $suburb[$a], $state[$a]);
In MYSQL, address.unit is NULLABLE and has no default value.
If I insert directly into the table and omit a value for the unit column; NULL is stored. Which I expected.
I suspect that the bind_param function changes NULL to 0 if the datatype for the column is specified as 'i' (integer), because NULLs passed to VARCHAR columns are stored as NULL.
Am I correct and if so how should I pass a NULL to the integer column?
To simplify my question (and because I didn't think it would be relevant) I omitted that the values where passing through a $mysqli->real_escape_string function and after some testing I found that it converts a NULL to an empty string
$test = "";
$test = (strlen($test)<1 ) ? NULL : $test;
var_dump($test); // null
echo "<br>";
$test = $mysqli->real_escape_string($test);
var_dump($test); // string '' (length=0)
This does not solve my problem but it does answer this question

Categories