mysql_num_rows error - sql

Cant figure out what the problem is!
$msgs = mysql_num_rows(mysql_query("SELECT * FROM messages WHERE recipient = $userID AND read = 0"));
echo $msgs;
The above code works if I remove "and read =0". But if not i get:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in left_menu.php on line 16.
I have a field in the table called read (tinyint 1,defualt 0)
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sender` int(10) unsigned NOT NULL DEFAULT '0',
`recipient` int(10) unsigned NOT NULL DEFAULT '0',
`subject` varchar(255) CHARACTER SET utf8 NOT NULL,
`message` text CHARACTER SET utf8,
`date` int(10) unsigned NOT NULL DEFAULT '0',
`read` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
INSERT INTO `messages` (`id`, `sender`, `recipient`, `subject`, `message`, `date`, `read`) VALUES
(1, 47, 13, 'Hello!', 'TEST!', 1228326055, 0),
(2, 536, 13, 'blblabla', 'yeah', 1248506708, 0);
Whats the problem?

read is a reserved keyword, so this generates a MySQL syntax error. However, at the MySQL prompt, this works:
SELECT * FROM messages WHERE recipient = 1 AND `read` = 0;
You'll have to backquote it in your PHP query.

What #Jeremy said, and you might want to adopt a different approach. Perform the query, check for errors, do other stuff on result (check num rows, read data etc).
Each action in it's own line, not "Babushka chained".

Related

MariaDB, How to copy existing records using insert?

I have a lot of existing records which I want to copy using an INSERT, for example if I have a query:
SELECT * FROM `threats` WHERE biDataset=9;
The common key is biDataset, the primary key in this table is biPK which is auto incremented on each insert. Here is the table structure:
CREATE TABLE `threats` (
`biPK` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
`biDataset` BIGINT(20) UNSIGNED NOT NULL COMMENT 'ID of dataset',
`jsonParams` LONGTEXT NOT NULL COMMENT 'JSON object containing all parameters' COLLATE 'utf8mb4_bin',
`txtTrainee` MEDIUMTEXT NULL DEFAULT NULL COMMENT 'Trainee host name (NULL if not applicable)' COLLATE 'utf8mb4_unicode_ci',
PRIMARY KEY (`biPK`) USING BTREE,
UNIQUE INDEX `dataset and json` (`biDataset`, `jsonParams`) USING HASH,
INDEX `datasetIdx` (`biDataset`) USING BTREE,
INDEX `jsonIdx` (`jsonParams`(768)) USING BTREE
)
COMMENT='Table of datasets'
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=174;
What I want to do is copy all the records that exist where biDataset is 9, creating new records, I need to be able to specify the new biDataset too, 15 to use for all copies instead of 9.
I've tried:
INSERT INTO `threats` (biDataset, txtTrainee, jsonParams)
SELECT 15, NULL, jsonParams FROM `threats` WHERE biDataset=9;
This results in:
SQL Error (1364): Field 'DB_ROW_HASH_1' doesn't have a default value
The solution was to modify the table structure to:
CREATE TABLE `threats` (
`biPK` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary key',
`biDataset` BIGINT(20) UNSIGNED NULL DEFAULT NULL COMMENT 'ID of dataset',
`jsonParams` LONGTEXT NULL DEFAULT NULL COMMENT 'JSON object containing all parameters' COLLATE 'utf8mb4_bin',
`txtTrainee` MEDIUMTEXT NULL DEFAULT NULL COMMENT 'Trainee host name (NULL if not applicable)' COLLATE 'utf8mb4_unicode_ci',
PRIMARY KEY (`biPK`) USING BTREE,
UNIQUE INDEX `dataset and json` (`biDataset`, `jsonParams`) USING HASH,
INDEX `datasetIdx` (`biDataset`) USING BTREE,
INDEX `jsonIdx` (`jsonParams`(768)) USING BTREE
)
COMMENT='Table of datasets'
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=174
;
This is bug of mariadb, and it is still unresolved...
Checkout: https://jira.mariadb.org/browse/MDEV-22756

'{"queue":[],"recieved":[],"accepted":[]}' not a valid query [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I'm receiving this error when trying to query a INSERT INTO request.
Table query:
CREATE TABLE `profiles` (
`userid` bigint(20) NOT NULL,
`balance` bigint(20) NOT NULL,
`respects` bigint(20) NOT NULL,
`tarowomaru` bigint(20) NOT NULL,
`taruwumaru` bigint(20) NOT NULL,
`suggestions` bigint(20) NOT NULL,
`friends` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`flags` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SQL query:
INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags)VALUES (323470201016549378, 0, 0, 0, 0, 0, '{"queue":[],"recieved":[],"accepted":[]}', '[]')
Received error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"queue":[],"recieved":[],"accepted":[]},[])' at line 17
Is there something wrong with {"queue":[],"recieved":[],"accepted":[]} or is there something wrong with my query? Is using get requests messing up the string?
I guess it was my query. My query before was
"INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags) VALUES ($userid, $balance, $respects, $tarowomaru, $taruwumaru, $suggestions, $friends, $flags)"
so it wasn't sending {"queue":[],"recieved":[],"accepted":[]} as a string.
The fixed query:
"INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags) VALUES ($userid, $balance, $respects, $tarowomaru, $taruwumaru, $suggestions, '$friends', '$flags')"
Thanks for you guy's help though!

Can't assign id, "Column 'id' cannot be null"

I inherited a database using Rails that doesn't set id incrementally, and also has two primary keys:
CREATE TABLE `t_user_history` (
`id` int(11) NOT NULL,
`history_no` int(11) NOT NULL,
`user_login_id` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`user_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`user_pass` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
`app_version` varchar(31) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`history_no`,`id`))
However, when I try to insert into this table using ruby as such:
tuser = TUserHistory.find_by_id(user.id)
TUserHistory.transaction do
ntuser = TUserHistory.new
ntuser.id = tuser.id
ntuser.history_no = 0
ntuser.user_login_id = tuser.user_login_id
ntuser.user_name = tuser.user_name
ntuser.user_pass = tuser.user_pass
ntuser.app_version = params[:app]
ntuser.save
I get the error:
getName {"error_code":"Mysql2::Error: Column 'id' cannot be null: INSERT INTO `t_user_history`
(`app_version`, `created_at`, `deleted_at`, `history_no`, `id`, `updated_at`, `user_login_id`, `user_name`, `user_pass`)
VALUES ('v1.2.9', '2012-08-30 09:26:57', NULL, 0, NULL, '2012-08-30 09:26:57', 'userlogin', 'username', 'userpass')"}
Even if I set ntuser.id = 9127 or some other value, it still says that 'id' cannot be null.
I looked at other answers that say it is indeed possible to modify this value, but it seems as though whatever value I attempt to set for ntuser.id gets ignored.
Trashing the table and starting again in a sane manner is not allowed, as this table is already being used by our services. I thought I'd create a new column for user_id, before I found out it didn't auto-increment, but even before getting to that step nothing, not even ntuser.id = 0 or deleting the line that defines ntuser.id, works.
What is going on here? Why isn't it recognizing the data is has been passed? What is the best (no, fastest) way to fix this?
Edit: Rails version 3.1.0
TUserHistory class:
class TUserHistory < ActiveRecord::Base
set_table_name "t_user_history"
default_scope select("id, user_login_id,user_name,user_pass,app_version")
acts_as_paranoid
end
Finally got around to doing it, by just doing an SQL statement. I wanted to use rails, seeing as how rails/ruby have wrappers for SQL code, but it just wasn't working. In the end, it looks like:
tuser = TUserHistory.order("history_no DESC").find_by_id(user.id) #get last entry
TUserHistory.transaction do
id = tuser.id
history_no = Integer(tuser.history_no)
intHist_no = history_no + 1 #because this column doesn't auto-increment
user_login_id = tuser.user_login_id
user_name = tuser.user_name
user_pass = tuser.user_pass
app_version = params[:app]
sql = "INSERT INTO t_user_history (id, history_no, user_login_id,user_name,user_pass,app_version) VALUES ('#{id}','#{intHist_no}','#{user_login_id}','#{user_name}','#{user_pass}','#{app_version}')"
ActiveRecord::Base.connection.execute(sql)
The only other thing that changed is that the class description for TUserHistory had history_no added so that it would return with the tuser select call, and could then be modified.

MySQL Error: ON DUPLICATE KEY UPDATE, column count doesn't match value count at row

Can anyone see why I'm getting this error is causing an error:
#1136 - Column count doesn't match value count at row 1
Here is the query:
INSERT INTO `people`
(`id`,`title`,`first_name`,`middle_initial`,`preferred_name`,`last_name`,
`home_phone`,`mobile_phone`,`email`,`gender`,`date_of_birth`,`qff`,`status`)
VALUES ('20','Mr','first','mid','pref','fam',
'home','mobile','email','male','0000-00-00','qff','active')
ON DUPLICATE KEY UPDATE
`people`.`id` = LAST_INSERT_ID(`people`.`id`),
`people`.`title` = 'Mr',
`people`.`first_name` = 'first',
`people`.`middle_initial` = 'mid',
`people`.`preferred_name` = 'pref',
`people`.`last_name` = 'fam',
`people`.`home_phone` = 'home',
`people`.`mobile_phone` = 'mobile',
`people`.`email` = 'email',
`people`.`gender` = 'male',
`people`.`date_of_birth` = '0000-00-00',
`people`.`qff` = 'qff',
`people`.`status` = 'active'
And the table structure:
CREATE TABLE `people` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` text,
`first_name` text,
`middle_initial` text,
`preferred_name` text,
`last_name` text,
`home_phone` text,
`mobile_phone` text,
`email` text,
`gender` enum('male','female') DEFAULT NULL,
`date_of_birth` date DEFAULT NULL,
`qff` varchar(20) NOT NULL,
`status` enum('active','inactive') NOT NULL,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_by` int(10) unsigned DEFAULT NULL,
`updated_by_type` enum('person','admin') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I had the exact same problem a while ago - for me the issue was related to a trigger on the table in question.
Recently I had the same problem, But I used batch insert/update ,my problem is not about trigger , its the 'foreach' problem, if u used the total 'foreach' like
<foreach collection="meters" index="index" item="meter" open="(" close=")" separator=",">
</foreach>
but the error code is
Error Code: 1136. Column count doesn't match value count at row 1 0.000 sec
for my test
it will add another () for your code (I didn't check the log).
so we can user
< foreach collection="medichines" index="index" item="medichine" separator=",">
(
)
< /foreach>
this way can fix you error

Dynamically removing records when certain columns = 0; data cleansing

I have a simple card table:
CREATE TABLE `users_individual_cards` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` char(36) NOT NULL,
`individual_card_id` int(11) NOT NULL,
`own` int(10) unsigned NOT NULL,
`want` int(10) unsigned NOT NULL,
`trade` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`individual_card_id`),
KEY `user_id_2` (`user_id`),
KEY `individual_card_id` (`individual_card_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
I have ajax to add and remove the records based on OWN, WANT, and TRADE. However, if the user removes all of the OWN, WANT, and TRADE cards, they go to zero but it will leave the record in the database. I would prefer to have the record removed. Is checking after each "update" to see if all the columns = 0 the only way to do this? Or can I set a conditional trigger with something like:
//psuedo sql
AFTER update IF (OWN = 0, WANT = 0, TRADE = 0) DELETE
What is the best way to do this? Can you help with the syntax?
Why not just fire two queries from PHP (or other front end)?
update `users_individual_cards` ...
delete `users_individual_cards` where ... (same condition) and own + want + trade = 0
The trigger will be:
CREATE TRIGGER users_individual_cards_trigger
AFTER UPDATE ON users_individual_cards
FOR EACH ROW
BEGIN
DELETE FROM users_individual_cards
WHERE 'OWN' = 0 AND 'WANT' = 0 AND 'TRADE' = 0;
END$$
The solutions throw the delete query will be better because not all versions of mysql support it.