How to use CHAR_LENGTH() in CREATE TABLE query - MYSQL - mysql

My question may sound vague but am going to try as much as possible to make it clear enough. Prior to this, I have made some research on the internet and other SO pages but to no avail.
Is it possible to use CHAR_LENGTH() function in a CREATE TABLE clause like we usually do in SELECT Clause :
SELECT CHAR_LENGTH("SQL Tutorial") AS LengthOfString;
What I want to do is similar to this:
CREATE TABLE `tbl_content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` varchar(32) NOT NULL,
`no_of_chars` int(4) NULL DEFAULT CHAR_LENGTH(`content`) ,
PRIMARY KEY (`id`)
)
But the above CREATE statement gives an error near CHAR_LENGTH.
Precisely, During insertion of a record into such a table, I want the server to be able to read the length of the content field and store in no_of_chars field as default value.
Is this POSSIBLE?

Yes, you could use generated column:
CREATE TABLE `tbl_content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` varchar(32) NOT NULL,
`no_of_chars` int(4) AS ( CHAR_LENGTH(`content`)) ,
PRIMARY KEY (`id`)
);
DBFiddle Demo

Related

I can't find what's wrong with this SQL script

I have a big script that I'm trying to execute. It's located here: https://github.com/diamondo25/mcdb-files/blob/master/mcdb-4.3-global-83/mcdb-4.3-global-83.sql.gz
However, I'm receviing the following errors:
I really tried everything but failed. I know it's a big script but unfortunately I have no other place than StackOverflow to ask for help. BTW I'm using MariaDB and MySQL query browser to execute it.
Here's the queries before line 28:
/*Data for the table `block_chat_reason_data` */
insert into `block_chat_reason_data`(`id`,`reason`,`message`) values (1,'Foul Language','Foul language/Harrassment'),(2,'Advertising','Advertising websites'),(3,'Hack','Fake GM'),(4,'Account Trading','Trading or selling account'),(5,'Trading','Do not report fame scams and trade scams. '),(6,'Penalty Alert','The reporter\'s conversation is also subject to penalties.');
/*Table structure for table `block_reason_data` */
DROP TABLE IF EXISTS `block_reason_data`;
CREATE TABLE `block_reason_data` (
`id` int(11) NOT NULL,
`block_type` varchar(15) NOT NULL DEFAULT '',
`message` varchar(120) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
You are not escaping comma, try
insert into `block_chat_reason_data`(`id`,`reason`,`message`) values (1,'Foul Language','Foul language/Harrassment'),(2,'Advertising','Advertising websites'),(3,'Hack','Fake GM'),(4,'Account Trading','Trading or selling account'),(5,'Trading','Do not report fame scams and trade scams. '),(6,'Penalty Alert','The reporter\''s conversation is also subject to penalties.');
Last comma is the problem on line 5.
So use this:
CREATE TABLE `block_reason_data`(
`id` int(11) NOT NULL,
`block_type` varchar(15) NOT NULL DEFAULT '',
`message` varchar(120) NOT NULL DEFAULT ''
PRIMARY KEY (`id`)
);

Unexpected beginning of statement

Hi I just followed a YouTube video and created this but it won't let me create the tables how do I fix it?
2 errors were found during analysis .
Unexpected beginning of statement. (near "member_id" at position 24)
Unrecognized statement type. (near "SMALLINT" at position 34)
CREATE TABLES members(
member_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(60) NOT NULL,
phone CHAR(10) NOT NALL DEFAULT'000000000',
membership_status ENUM('gold','silver,''bronze','nam') NOT NULL DEFAULT'nam',
PRIMARY KEY (member_id)
)
You had multiple typos (missing single quote, you wrote NAL instead of NULL). This query will work:
CREATE TABLE `members` (
`member_id` SMALLINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(60) NOT NULL,
`phone` CHAR(10) NOT NULL DEFAULT '000000000',
`membership_status` ENUM('gold', 'silver', 'bronze', 'nam') NOT NULL DEFAULT 'nam',
PRIMARY KEY (`member_id`));
Furthermore you may want to look into different tutorials. In my oppinion no one should use ENUMs anymore, because of several disadvantages. Maybe someone can write a good tutorial tip here. Maybe this is something for you: https://www.codecademy.com/learn/learn-sql
CREATE TABLES members(
member_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(60) NOT NULL,
phone CHAR(10) NOT NALL DEFAULT'000000000',
membership_status ENUM('gold','silver,''bronze','nam') NOT NULL DEFAULT'nam',
PRIMARY KEY (member_id)
);
Try by doing this. As it seems, there is no ; mark in the closing.
Try changing create tables to create table.

Error while creating a MySql table

I am trying to create a table from my command line (Debian), but it keeps saying I have an error in my syntax. To me it looks fine and I have got it checked by 2 different people who also cannot find the issue.
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT,
uuid VARCHAR(32) NOT NULL,
key VARCHAR(50) NOT NULL
);
One guy said remove NOT NULL but I still had the same issue.
KEY is a reserved word try change with my_key
CREATE TABLE users (id INT( 6) UNSIGNED AUTO_INCREMENT,
uuid VARCHAR(32) NOT NULL,
my_key VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`));
Sorry,
for an AUTO_INCREMENT Field you MUST have a key on this COLUMN.
So this works:
CREATE TABLE `user` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(32) DEFAULT NULL,
`key` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
MySQL has lots of reserved keywords that cannot be used as column names. Here you are using key as a column name, and since it is a reserved keyword in MySQL, you need to change the name of the column to something that is not a reserved keyword.
You can find a full list of reserved keywords that cannot be used as a column name here.
The column name "key" you used for the third column is a reserved word, all you have to do is change the name.
Well, one probably can't know all the existing keywords in a programming language but one can help himself/herself by using colour-code enabled text editor or Integrated Development Environment (IDE) when writing codes. It helps a lot.

How to optimized mysql query having large dataset

I have two tables with the following schema,
CREATE TABLE `open_log` (
`delivery_id` varchar(30) DEFAULT NULL,
`email_id` varchar(50) DEFAULT NULL,
`email_activity` varchar(30) DEFAULT NULL,
`click_url` text,
`email_code` varchar(30) DEFAULT NULL,
`on_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `sent_log` (
`email_id` varchar(50) DEFAULT NULL,
`delivery_id` varchar(50) DEFAULT NULL,
`email_code` varchar(50) DEFAULT NULL,
`delivery_status` varchar(50) DEFAULT NULL,
`tries` int(11) DEFAULT NULL,
`creation_ts` varchar(50) DEFAULT NULL,
`creation_dt` varchar(50) DEFAULT NULL,
`on_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The email_id and delivery_id columns in both tables make up a unique key.
The open_log table have 2.5 million records where as sent_log table has 0.25 million records.
I want to filter out the records from open log table based on the unique key (email_id and delivery_id).
I'm writing the following query.
SELECT * FROM open_log
WHERE CONCAT(email_id,'^',delivery_id)
IN (
SELECT DISTINCT CONCAT(email_id,'^',delivery_id) FROM sent_log
)
The problem is the query is taking too much time to execute. I've waited for an hour for the query completion but didn't succeed.
Kindly, suggest what I can do to make it fast since, I have the big data size in the tables.
Thanks,
Faisal Nasir
First, rewrite your query using exists:
SELECT *
FROM open_log ol
WHERE EXISTS (SELECT 1
FROM send_log sl
WHERE sl.email_id = ol.email_id and sl.delivery_id = ol.delivery_id
);
Then, add an index so this query will run faster:
create index idx_sendlog_emailid_deliveryid on send_log(email_id, delivery_id);
Your query is slow for a variety of reasons:
The use of string concatenation makes it impossible for MySQL to use an index.
The select distinct in the subquery is unnecessary.
Exists can be faster than in.
If this request is often on, you can greatly increase it by create bigint id column, enven if it not unique.
For example you can put trigger and create column like this
alter table sent_log for_get bigint;
After that create trigger/ update it to put hash into that bigint
for_get=CONV(substr(md5(concat(email_id, delivery_id)),1,10),16,10)
If you have such column in both table and index on it, query will be like
SELECT *
FROM open_log ol
left join send_log sl on sl.for_get=ol.for_get
WHERE sl.email_id is not null and sl.email_id = ol.email_id and sl.delivery_id = ol.delivery_id;
That query will be fast.

What is the best way to have a varchar primary key column with an auto-increment?

I would like to create some tables in MySQL. One table would be for users, one for topics, one for comments, and so on.
I need each table to have its own ID column in the following format:
USERS table: ID column
Values:
USR00001
USR00002
USR00003
..
..
USR99999
where as topics table would have IDs like:
TPC00001
TPC00002
TPC00003
similarly, the comments table would have the following IDs:
CMT00001
CMT00002
I tried to use UNIQUE key but did not work: (inspired by this answer)
CREATE TABLE `users` (
`ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT ,
`firstname` VARCHAR(100) NOT NULL ,
`lastname` VARCHAR(100) NOT NULL ,
`email` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`ID`)
UNIQUE KEY ( 'USR' + `ID`)
);
Can it be done using triggers (Before Insert) maybe?
Please note that I don't want to handle the insertion of the primary keys on the application level. I would prefer the database engine to handle all the work for that.