mysql default value error - mysql

I'm testing a link-shortener Sinatra application that uses a mysql database. When I enter a link to be shortened, I'm getting this mysql error
(mysql_errno=1364, sql_state=HY000) Field 'link_identifier' doesn't have a default value Query: INSERT INTO `urls` (`original`) VALUES ('http://pryrepl.org/screencasts.html')
I'm assuming that means field link_identifier should have a default value
urls and visits tables both have link_identifier field, but the links table doesn't. However, in the code that creates the tables, copied below, it's the Link class that has the `property :identifier.' Does anyone know how I would fix this problem?
mysql> show columns from urls;
+-----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| original | varchar(255) | YES | | NULL | |
| link_identifier | varchar(50) | NO | MUL | NULL | |
+-----------------+------------------+------+-----+---------+----------------+
3 rows in set (0.12 sec)
mysql> show columns from visits
-> ;
+-----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime | YES | | NULL | |
| ip | varchar(39) | YES | | NULL | |
| country | varchar(50) | YES | | NULL | |
| link_identifier | varchar(50) | NO | MUL | NULL | |
+-----------------+------------------+------+-----+---------+----------------+
5 rows in set (0.08 sec)
mysql> show columns from links
-> ;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| identifier | varchar(50) | NO | PRI | NULL | |
| created_at | datetime | YES | | NULL | |
+------------+-------------+------+-----+---------+-------+
Code
class Url
include DataMapper::Resource
property :id, Serial
property :original, String, :length => 255
belongs_to :link
end
....
class Link
include DataMapper::Resource
property :identifier, String, :key => true
property :created_at, DateTime
has 1, :url
has n, :visits
...
class Visit
include DataMapper::Resource
property :id, Serial
property :created_at, DateTime
property :ip, IPAddress
property :country, String
belongs_to :link
after :create, :set_country
....
Update - the source code already seems to have a way to create a link identifier to satisfy the requirements of mysql, but it doesn't seem to be working
def self.create_link(original)
url = Url.create(:original => original)
if Link.first(:identifier => url.id.to_s(36)).nil? or !DIRTY_WORDS.include? url.id.to_s(36)
link = Link.new(:identifier => url.id.to_s(36))
link.url = url
link.save
return link
else
create_link(original)
end
end
end

The error means you are not setting a value for link_identifier in your insert statement. And link_identifier cannot be null by table definition.
You need to specify a value for link_identifier. Example
INSERT INTO `urls` (`original`, `link_identifier`)
VALUES ('http://pryrepl.org/screencasts.html', 'value_for_link_identifier')

When sending the query
INSERT INTO `urls` (`original`) VALUES ('http://pryrepl.org/screencasts.html')
the value for link_identifier isn't set.
You defined the urls table as
mysql> show columns from urls;
+-----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| original | varchar(255) | YES | | NULL | |
| link_identifier | varchar(50) | NO | MUL | NULL | |
+-----------------+------------------+------+-----+---------+----------------+
3 rows in set (0.12 sec)
The default value for link_identifier is NULL (or not set), but since the value cannot be NULL, mysql doesn't know what to set as value.
Change the mysql query into
INSERT INTO `urls` (`original`, `link_identifier`) VALUES ('http://pryrepl.org/screencasts.html', '<your identifier here>')

Related

desc table in mysql say Null is No but default is NULL?

I am using mysql for a project. When I did 'desc table_name', I see that the tabular output shows the Null of the field is set to No, but then 'Default' is set to NULL. How can a field not have a Null but then default is Null itself?
mysql> desc users;
+-----------------+------------------+------+-----+----------------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+----------------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| email | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| remember_token | varchar(100) | YES | | NULL | |
| profile_pic | varchar(255) | YES | | img/profile/profilepic.jpg | |
| activation_code | varchar(255) | YES | UNI | NULL | |
| status_id | int(10) unsigned | NO | MUL | 1 | |
| profile_id | int(10) unsigned | YES | MUL | NULL | |
+-----------------+------------------+------+-----+----------------------------+----------------+
10 rows in set (0.00 sec)
This is a perfectly legal combination. It means that when you try to insert a new row and do not explicitly specify this column's value, it would default to null and thus error out. This combination is often used as a way to force you to explicitly assign a value to the column instead of just relying on defaults.
we should know this:
Null(NO): means this column couldn't accept a "NULL" value
Null(YES): means this column could accept a "NULL" value
Default: means this column's default value :)
we should know: in MySQL, blank is not equal to NULL, if we insert nothing into a column, it will stay nothing(it will not insert a "NULL" into this column)
so, when Null(NO) comes with Default(NULL), if we insert nothing to this value, it'll have a default value "NULL" and it 'll conflict with the constraint, then it'll throw a exception

Create table with date column

I want to create a student table with column 'student_birthday' and its format should be dd-mm-yy.
create table `student`.`studentinfo`(
`student_id` int(10) not null auto_increment,
`student_name` varchar(45) not null,
`student_surname` varchar(45) not null,
`student_birthday` date(???),
(some lines of code)
primary key(student_id));
what should be inputted in the (???) to get the right format above?
Just use "DATE" without the brackets. The brackets are only needed for certain column types where you want to specify the maximum number of bytes/characters that can be stored.
For MySQL, it's documented at https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
The following example will explain your problem. I am using MySQL 5.7.18.
Firstly I have described the structure of users table as I am going to create posts table with FOREIGN KEY.
Later I created posts table and it has a DATE field named created with many other columns.
Finally I inserted 1 row in the newly created table.
mysql> desc users;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| fname | varchar(50) | NO | | NULL | |
| lname | varchar(50) | NO | | NULL | |
| uname | varchar(20) | NO | | NULL | |
| email | text | NO | | NULL | |
| contact | bigint(12) | NO | | NULL | |
| profile_pic | text | NO | | NULL | |
+-------------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)
mysql> CREATE TABLE posts(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, title text NOT NULL, description text NOT NULL, posted_by bigint, FOREIGN KEY(posted_by) REFERENCES users(id) ON DELETE CASCADE ON UPDATE RESTRICT , created DATE);
Query OK, 0 rows affected (0.01 sec)
mysql> desc posts;
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| title | text | NO | | NULL | |
| description | text | NO | | NULL | |
| posted_by | bigint(20) | YES | MUL | NULL | |
| created | date | YES | | NULL | |
+-------------+------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> INSERT INTO posts(title, description, posted_by, created) values("Getting started with MySQL", "Excellent Database system", 1, "2017-05-26");
Query OK, 1 row affected (0.00 sec)
mysql> select * from posts;
+----+----------------------------+---------------------------+-----------+------------+
| id | title | description | posted_by | created |
+----+----------------------------+---------------------------+-----------+------------+
| 1 | Getting started with MySQL | Excellent Database system | 1 | 2017-05-26 |
+----+----------------------------+---------------------------+-----------+------------+
1 row in set (0.00 sec)
mysql>
The datatype date on its own is enough to represent a date value. The format will matter when you are displaying the data, for which you can use the FORMAT function on your date column.
I should add that there is a certain amount of flexibility as to the format when inserting date time literals as documented here.

Need other than id as a primary key in rails active record migration script

I have a table called students
mysql> desc students;
+--------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| height | decimal(15,8) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| text | varchar(255) | YES | | NULL | |
| status | tinyint(4) | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+--------------------+---------------+------+-----+---------+----------------+
I want to create a new table called students_data which has student_name as foreign key and name as primary key from students table. How should I change my script? The following script takes id as primary key from students table
class CreateStudentsData < ActiveRecord::Migration
def change
create_table :students_data do |t|
t.belongs_to :students, :foreign_key => :student_name, :primary_key => :name
end
end
end
How should I change my script to get name as primary key?
NOTE: I don't want to set primary_key id as false as suggested here. I need id and name both as primary key.
Take a look at the following link
http://ruby-journal.com/how-to-override-default-primary-key-id-in-rails/

mysql trigger when no match found

I'm trying to setup a mysql trigger. So lets assume the table is like this
mysql> explain users;
+------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| purge_date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+------+-----+-------------------+-----------------------------+
and
mysql> explain users_details;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
so the trigger i have setup will create a purge_date of NOW on the users table when something is removed from the users_details table. This is fine.
The issue is that sometimes the data for the users_details table comes through incorrectly and then the users update it so then i need to remove the purge_date if they re-insert the data. Now I have made this trigger
CREATE TRIGGER purge_fix AFTER INSERT ON users_details
FOR EACH ROW
BEGIN
UPDATE users
SET purge_date= '0000-00-00 00:00:00'
WHERE users.name = NEW.name;
END;
Which works fine but in some situations there will not be a link between the users_details table and the users table (it will be created at a later stage) so my question is, as the trigger will fail in some situations (which is 100% fine by me), will I be breaking something having the trigger failing?

Rails 3 app - problem with saving integer to column with data type int(11)

I have following a structure of MySQL table:
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| reg | int(11) | NO | | NULL | |
| descr | text | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+------------+----------+------+-----+---------+----------------+
And with this way I am saving data to my database:
#saving = Table.new(:reg => 1234, :descr => params[:descr]).save
And my problem is - I don't know how it is possible, but this query does not save the number to column "reg". I am getting this error
Mysql2::Error: Column 'reg' cannot be null: INSERT INTOname_of_table(updated_at,descr,reg,created_at) VALUES ('2011-06-06 20:40:43', 'description of man', NULL, '2011-06-06 20:40:43')
I worked a lot with PHP and MySQL database, but this error I never got...
Where's the problem?
if you look at your schema, it says the default for :reg is NULL, and that it can not be NULL -- that might cause the problem you see
can you change the schema to allow :reg to be NULL and try again?