I have the same problem, and do not understand the answer #5343141 titled "The proper way to insert a NULL into a database with CodeIgniter". I tried all given answers, without success.
This is my MySQL table:
The 2 last columns:
`id_etablissement_commanditaire` int(10) unsigned DEFAULT NULL,
`id_etablissement_payeur` int(10) unsigned DEFAULT NULL,
that makes problem, do have "NULL", so they accept NULL value (tried with phpMyAdmin, it works).
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `contacts` (
`id_contact` int(10) unsigned NOT NULL AUTO_INCREMENT,
`service` varchar(50) NOT NULL,
`civilite` set('Monsieur','Madame') NOT NULL,
`prenom` varchar(50) NOT NULL,
`nom` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
`tel_fixe` varchar(14) NOT NULL,
`tel_mobile` varchar(14) NOT NULL,
`fax` varchar(14) NOT NULL,
`id_etablissement_commanditaire` int(10) unsigned DEFAULT NULL,
`id_etablissement_payeur` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id_contact`),
KEY `id_etablissement_payeur` (`id_etablissement_payeur`),
KEY `id_etablissement_commanditaire` (`id_etablissement_commanditaire`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=28 ;
ALTER TABLE `contacts`
ADD CONSTRAINT `contacts_ibfk_2` FOREIGN KEY (`id_etablissement_payeur`) REFERENCES `etablissements_payeurs` (`id_etablissement_payeur`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `contacts_ibfk_3` FOREIGN KEY (`id_etablissement_commanditaire`) REFERENCES `etablissements_commanditaires` (`id_etablissement_commanditaire`) ON DELETE NO ACTION ON UPDATE NO ACTION;
This is my CodeIgniter controller code :
1) I need to initialize $_POSTs to '' if they do not exist.
if ( ! isset( $_POST['action'] ) ) $_POST['action'] = '';
if ( ! isset( $_POST['id_contact'] ) ) $_POST['id_contact'] = '';
if ( ! isset( $_POST['service'] ) ) $_POST['service'] = '';
if ( ! isset( $_POST['civilite'] ) ) $_POST['civilite'] = '';
if ( ! isset( $_POST['prenom'] ) ) $_POST['prenom'] = '';
if ( ! isset( $_POST['nom'] ) ) $_POST['nom'] = '';
if ( ! isset( $_POST['email'] ) ) $_POST['email'] = '';
if ( ! isset( $_POST['tel_fixe'] ) ) $_POST['tel_fixe'] = '';
if ( ! isset( $_POST['tel_mobile'] ) ) $_POST['tel_mobile'] = '';
if ( ! isset( $_POST['fax'] ) ) $_POST['fax'] = '';
if ( ! isset( $_POST['id_etablissement_commanditaire'] ) ) $_POST['id_etablissement_commanditaire'] = NULL;
if ( ! isset( $_POST['id_etablissement_payeur'] ) ) $_POST['id_etablissement_payeur'] = NULL;
For the last 2 if, I tried to initialize to '' and NULL, but none works.
2) Insert into database :
$donnees = array(
'service'=> $_POST['service'],
'civilite'=> $_POST['civilite'],
'prenom'=> $_POST['prenom'],
'nom'=> $_POST['nom'],
'email'=> $_POST['email'],
'tel_fixe'=> $_POST['tel_fixe'],
'tel_mobile'=> $_POST['tel_mobile'],
'fax'=> $_POST['fax'],
'id_etablissement_commanditaire'=> $_POST['id_etablissement_commanditaire'] ,
'id_etablissement_payeur'=> $_POST['id_etablissement_payeur']);
$this->db->insert('contacts', $donnees);
If I add an empty record CodeIgniter says :
Error Number: 1452
Cannot add or update a child row: a foreign key constraint fails (`france-medical-transport`.`contacts`, CONSTRAINT `contacts_ibfk_2` FOREIGN KEY (`id_etablissement_payeur`) REFERENCES `etablissements_payeurs` (`id_etablissement_payeur`) ON DELETE NO ACTION )
INSERT INTO `contacts` (`service`, `civilite`, `prenom`, `nom`, `email`, `tel_fixe`, `tel_mobile`, `fax`, `id_etablissement_commanditaire`, `id_etablissement_payeur`) VALUES ('', '', '', '', '', '', '', '', '', '')
Try changing your DB insert script to not include the columns at all if they have no value:
$donnees = array(
'service'=> $_POST['service'],
'civilite'=> $_POST['civilite'],
'prenom'=> $_POST['prenom'],
'nom'=> $_POST['nom'],
'email'=> $_POST['email'],
'tel_fixe'=> $_POST['tel_fixe'],
'tel_mobile'=> $_POST['tel_mobile'],
'fax'=> $_POST['fax']);
if ($this->input->post('id_etablissement_commanditaire')) $donnees['id_etablissement_commanditaire'] = $this->input->post('id_etablissement_commanditaire');
if ($this->input->post('id_etablissement_payeur')) $donnees['id_etablissement_payeur'] = $this->input->post('id_etablissement_payeur');
$this->db->insert('contacts', $donnees);
This will allow MySQL to insert the default NULL value without getting confused by any values you're trying to pass in, like an explicit NULL or an empty string.
A good way to do this is :
$this->db->set('id_etablissement_commanditaire' , $_POST['id_etablissement_commanditaire'] , FALSE );
$this->db->set('id_etablissement_payeur' , $_POST['id_etablissement_payeur'] , FALSE );
$this->db->insert('contacts');
This way, the last argument FALSE, means, NULL values won't be escaped, then I have NULL and not 'NULL'.
It works.
Nota : FALSE remove '', but it removes `` as well.
Related
This is the table layout:
CREATE TABLE camera
(
entity_id VARCHAR(50) PRIMARY KEY NOT NULL,
area_type INT(11) NOT NULL,
type INT(11),
`from` INT(11),
`to` INT(11),
severity INT(11) NOT NULL,
description VARCHAR(255),
additional_information VARCHAR(255),
location POINT NOT NULL,
reported_at DATETIME NOT NULL,
road_id INT(11) NOT NULL,
ugc TINYINT(1) COMMENT 'user generated content',
event INT(11),
advice VARCHAR(255),
updated_at DATETIME NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE UNIQUE INDEX camera_from_to_unique ON camera (`from`, `to`);
And this is the query:
INSERT INTO `camera`
(
`entity_id`,
`area_type`,
`type`,
`from`,
`to`,
`severity`,
`description`,
`additional_information`,
`location`,
`reported_at`,
`road_id`,
`ugc`,
`event`,
`advice`
) VALUES (
:id_28,
:area_type_28,
:type_28,
:from_28,
:to_28,
:severity_28,
:description_28,
:additional_information_28,
POINT(:position_x_28, :position_y_28),
:reported_at_28,
:road_id_28,
:ugc_28,
:event_28,
:advice_28
) ON DUPLICATE KEY UPDATE
`entity_id` = :id_28,
`area_type` = :area_type_28,
`type` = :type_28,
`from` = :from_28,
`to` = :to_28,
`severity` = :severity_28,
`description` = :advice_28,
`additional_information` = :description_28,
`location` = POINT(:position_x_28, :position_y_28),
`reported_at` = :reported_at_28,
`road_id` = :road_id_28,
`ugc` = :ugc_28,
`event` = :event_28,
`advice` = :advice_28
And these are the binded parameters:
array (
'id_28' => 'NLSIT0020843410',
'area_type_28' => 1,
'type_28' => 46,
'from_28' => 7775,
'to_28' => 683756,
'severity_28' => 80,
'description_28' => '',
'additional_information_28' => 'Tussen knp. Hattemerbroek en Zwolle-Noord',
'position_x_28' => 6.032483,
'position_y_28' => 52.490729000000002,
'reported_at_28' => '2017-01-06 16:43:00',
'road_id_28' => 621453,
'ugc_28' => 0,
'event_28' => 1072,
'advice_28' => '',
)
I thought that because my from and to field are both in the same unique index in my table, the ON DUPLICATE KEY UPDATE would be triggered, but apparently that is not the case.
Could someone please explain why my ON DUPLICATE KEY UPDATE is not triggered so the data gets updated instead of this mysql error?
The duplicate key update part of the insert is being activated. However the attempt to update the row instead of inserting is failing. Because of this.
) ON DUPLICATE KEY UPDATE
`entity_id` = :id_28,
`area_type` = :area_type_28,
`type` = :type_28,
`from` = :from_28, /* this one */
`to` = :to_28, /* and this one */
YOu are trying to force mysql to have the same values for the from and to columns that triggered the duplicate. You need to remove those two columns from the ON DUPLICATE KEY clause. So we have
ON DUPLICATE KEY UPDATE
`entity_id` = :id_28,
`area_type` = :area_type_28,
`type` = :type_28,
`severity` = :severity_28,
`description` = :advice_28,
`additional_information` = :description_28,
`location` = POINT(:position_x_28, :position_y_28),
`reported_at` = :reported_at_28,
`road_id` = :road_id_28,
`ugc` = :ugc_28,
`event` = :event_28,
`advice` = :advice_28
I created the first table for my plugin, and after working on adding more features I realized I needed to add a second table for an additional type of data.
Troubleshooting efforts so far have resolved the issue with dbDelta() not using the same variable name for the sql data, running dbDelta() both as a combined sql var ($setup_sql .= '...' instead of $setup_sql = '...'), and also running the code as a simple function rather than a class.
I even tried running a single table creation with a different name, just to check the code worked, and it still didn't create another table.
I have had no errors running through all these tests, and for all intents and purposes it seems that Wordpress doesn't allow a plugin to create more than one table - but I know that's not the case.
class activation_setup {
public static function wpd_activate() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$wpd_table_trig = $wpdb->prefix . 'wpd_triggers';
$setup_sql_trig = "CREATE TABLE $wpd_table_trig (
id int(11 ) NOT NULL AUTO_INCREMENT,
trigger varchar(255) DEFAULT NULL,
popup varchar(255) DEFAULT NULL,
notify varchar(255) DEFAULT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
dbDelta( $setup_sql_trig );
$wpd_table_sel = $wpdb->prefix . 'wpd_selections';
$setup_sql_sel = "CREATE TABLE $wpd_table_sel (
id int(11 ) NOT NULL AUTO_INCREMENT,
selected varchar(255) DEFAULT NULL,
session varchar(255) DEFAULT NULL,
ip varchar(255) DEFAULT NULL,
page varchar(255) DEFAULT NULL,
date varchar(255) DEFAULT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
dbDelta( $setup_sql_sel );
update_option('wpd_activated',true);
}
}
$activation_setup = new activation_setup();
register_activation_hook( __FILE__ , array( $activation_setup, 'wpd_activate' ) );
I'm going absolutely nuts trying to work out WHY this code doesn't add the second table, even after stripping out the duplicate table code and running it with a different table name.
I've through a ton of blog posts and Stack answers trying to get to the bottom of it.
Any help would be fantastic.
Issue is with the table definition.
You've written trigger in your table definition it is keyword also for mysql.
That was the issue.
Your problem will be solved by this change.
Use "`" when writing field name.
class activation_setup {
public static function wpd_activate() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$wpd_table_trig = $wpdb->prefix . 'wpd_triggers';
$setup_sql_trig = "CREATE TABLE $wpd_table_trig (
`id` int(11 ) NOT NULL AUTO_INCREMENT,
`trigger` varchar(255) DEFAULT NULL,
`popup` varchar(255) DEFAULT NULL,
`notify` varchar(255) DEFAULT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
dbDelta( $setup_sql_trig );
$wpd_table_sel = $wpdb->prefix . 'wpd_selections';
$setup_sql_sel = "CREATE TABLE $wpd_table_sel (
`id` int(11 ) NOT NULL AUTO_INCREMENT,
`selected` varchar(255) DEFAULT NULL,
`session` varchar(255) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`page` varchar(255) DEFAULT NULL,
`date` varchar(255) DEFAULT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
dbDelta( $setup_sql_sel );
}
}
$activation_setup = new activation_setup();
register_activation_hook( __FILE__ , array( $activation_setup, 'wpd_activate' ) );
If you want to make sure that issue is with that trigger then remove "`" from trigger field and then again activate plugin.
I have my databse: public
I have my table: info
in row files of player Maria i have this:
['python22.dll', ''], ['python27.dll', ''], ['channel.inf', ''], ['devil.dll', ''],['is_hack.exe', '']
The first 4 is normal so I don't want to see them in the list .. i just want to catch the "is_hack.exe"
My mysql query to get all ( including my normal files) is:
query("SELECT files FROM public.info WHERE player = 'Maria' ORDER BY actual_time DESC LIMIT 0,1;")
I need to see all the names that are not mine. Like:
FILE_FROM_OUTSIDE1 = is_hack.exe
FILE_FROM_OUTSIDE2 = stackoverflow.dll
If you know about LUA, i can get the entire query results to LUA then begin to parse.. but how?
EDIT:
This is my table:
CREATE TABLE `info` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`player` varchar(12) DEFAULT NULL,
`type_check` varchar(10) DEFAULT NULL,
`normal` varchar(20) DEFAULT NULL,
`actual` int(3) DEFAULT NULL,
`actual_time` varchar(20) DEFAULT NULL,
`files` varchar(3000) DEFAULT NULL,
PRIMARY KEY (`id`)
In "files" i have all this:
['python22.dll', ''], ['python27.dll', ''], ['channel.inf', ''], ['devil.dll', ''],['is_hack.exe', '']
I just want to select the is_hack.exe .. like: print is_hack.exe
I'm not sure if this is what you want. But i think this might help:
Replace the filename_field with your col name.
query("SELECT files FROM public.info WHERE player = 'Maria' AND filename_field = 'is_hack.exe' ORDER BY actual_time DESC LIMIT 0,1;")
UPDATE
I don't know if this I'm right but you should not save data like this. You can create a files table and specify which user own each row. Like:
CREATE TABLE `playerfiles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`player` int(11) DEFAULT NULL,
`filename` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`)
);
Then you can retrieve data with JOIN.
SELECT * FROM `info`
JOIN `playerfiles` ON `playerfiles.player` = `info.id`
WHERE `info.player` = 'Maria' and `playerfiles.filename` = 'THE NAME'
I'm trying to convert the following query in to a dataprovider, so it can be displayed within a CGridView. I have tried using a CArrayDataProvider, but have not had any luck so far, any help would be much appreciated!
Here is the query
public function getTeamsByLevelIdAndCompetitionId($levelId, $competitionId)
{
$query = "SELECT t.*,
(SELECT COUNT(*)
FROM tbl_competition_teams ct
WHERE ct.team = t.id
AND ct.competition = :competitionId) AS 'inCompetition'
FROM tbl_teams t
WHERE t.level = :levelId";
$params = array(
'levelId' => $levelId,
'competitionId' => $competitionId
);
$result = array();
$teams = $this->findAllBySQL($query, $params);
return $teams;
}
This is how I tried to make it in to a CArrayDataProvider:
public function getTeamsByLevelIdAndCompetitionId($levelId, $competitionId)
{
$rawData = Yii::app()->db->createCommand("SELECT t.*,
(SELECT COUNT(*)
FROM tbl_competition_teams ct
WHERE ct.team = t.id
AND ct.competition = :competitionId) AS 'inCompetition'
FROM tbl_teams t
WHERE t.level = :levelId")->queryAll();
$params = array(
'levelId' => $levelId,
'competitionId' => $competitionId
);
return new CArrayDataProvider($rawData, array(
'id'=>'id',
'sort'=>array(
'attributes'=>array(
'id', 'title', 'club', 'level', 'inCompetition',
),
),
));
}
but that gives me the error "CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound."
Here is my teams table
CREATE TABLE `tbl_teams` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(35) NOT NULL DEFAULT '',
`level` int(10) unsigned DEFAULT NULL,
`club` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2952 ;
and my competition teams table
CREATE TABLE `tbl_competition_teams` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`competition` int(10) unsigned NOT NULL DEFAULT '0',
`team` int(10) unsigned NOT NULL DEFAULT '0',
`seasonId` int(11) NOT NULL DEFAULT '3',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=126320 ;
Thanks a million in advance for any advice!
Maybe the problem is you queryAll() execute the query. At this momento you are not assigning the values to you parameters
$rawData = Yii::app()->db->createCommand("SELECT t.*,
(SELECT COUNT(*)
FROM tbl_competition_teams ct
WHERE ct.team = t.id
AND ct.competition = $competitionId) AS 'inCompetition'
FROM tbl_teams t
WHERE t.level = $levelId")->queryAll();
also you can try to rewrite your query.
$query = "SELECT t.*,
(SELECT COUNT(*)
FROM tbl_competition_teams ct
WHERE ct.team = t.id
AND ct.competition = :competitionId) AS 'inCompetition'
FROM tbl_teams t
WHERE t.level = :levelId";
$command= Yii::app()->db->createCommand($query);
$command->bindValue(':levelId', $levelId);
$command->bindValue(':competitionId', $competitionId);
$rawData = $command->queryAll();
$order = new Application_Model_DbTable_Order();
$orderno = $order->select()
->from($order, 'orderno')
->where('memberid = ?', $userid)
->order('orderno DESC')
->limit(1, 0);
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'SELECT ordertable.orderno FROM ordertable WHERE (memberid = '30') ORDER BY orderno DESC LIMIT 1' for column 'orderno' at row 1
Got this error and am wondering if there is anything wrong with my code, because I have searched everywhere for the cause but don't seem to find any help.
#SQL code for Ordertable#
`orderno` int(5) NOT NULL AUTO_INCREMENT,
`memberid` int(5) DEFAULT NULL,
PRIMARY KEY (`orderno`)
#SQL code for Item#
`itemid` int(5) NOT NULL AUTO_INCREMENT,
`image` varchar(100) NOT NULL,
`itemname` varchar(30) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
`itemtype` varchar(20) DEFAULT NULL,
PRIMARY KEY (`itemid`)
#SQL code for Orderdetail#
`orderdetailno` int(5) NOT NULL AUTO_INCREMENT,
`orderno` int(5) NOT NULL,
`itemid` int(5) NOT NULL,
`unitcost` decimal(6,2) DEFAULT NULL,
PRIMARY KEY (`orderdetailno`),
KEY `orderno` (`orderno`),
KEY `itemid` (`itemid`)
This is my sql code if it helps I'm using MySQL.
$request = new Zend_Session_Namespace('cart');
$auth = Zend_Auth::getInstance();
$user = $auth->getIdentity();
$userid = $user->userid;
$order = new Application_Model_DbTable_Order();
$itemdb = new Application_Model_DbTable_Item();
$orderdetail = new Application_Model_DbTable_Orderdetail();
$data = array ('memberid' => $userid);
$order->insert($data);
$orderno = $order->select()
->from($order, 'orderno')
->where('memberid = ?', $userid)
->order('orderno DESC')
->limit(1, 0);
foreach ($request->array as $var)
{
$unitprice = $itemdb->select()
->from('$itemdb', 'unitcost')
->where('itemid = ?', $var);
$newArray = array('orderno' => $orderno,
'itemid' => $var,
'unitcost' => $unitprice, );
$orderdetail->insert($newArray);
}
Any guidance will be very much appreciated.
Per https://stackoverflow.com/a/8882396/1432614, run
SELECT ##GLOBAL.sql_mode;
SELECT ##SESSION.sql_mode;
and if either include STRICT_TRANS_TABLES, remove it from the setting.
For example:
SET ##GLOBAL.sql_mode= 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
The reason you are getting that error is because you are attempting to use a Zend_Db_Select object as a value in your INSERT statement.
$orderno = $order->select()
->from($order, 'orderno')
->where('memberid = ?', $userid)
->order('orderno DESC')
->limit(1, 0);
And then inside the foreach loop:
$newArray = array('orderno' => $orderno, // <-- this becomes a SELECT statment
'itemid' => $var,
'unitcost' => $unitprice, );
$orderdetail->insert($newArray); // attempting to insert a select statement
You should execute the $orderno statement and fetch() the result if you want to use it in an insert statement:
$ordernum = $orderno->query()->fetch();
$newArray = array('orderno' => $ordernum,
'itemid' => $var,
'unitcost' => $unitprice, );
$orderDetail->insert($newArray);