I am new to mySQL and Netbeans7.3.1. I got a database set up and the connection all ready to go. I created one table and that worked out alright except it wouldn't let me use auto_increment.
Now I am trying to create a table using the information from:
http://docs.oracle.com/cd/E19957-01/mysql-refman-6.0/tutorial.html#example-auto-increment
and no matter what I do, I keep getting error messages even though I am doing just what the tutorial said.
Error code -1, SQL state 42X01: Syntax error: Encountered "(" at line 2, column 13.
Line 1, column 1
Error code -1, SQL state 42X05: Table/View 'ANIMALS' does not exist.
Line 8, column 1
Error code -1, SQL state 42X05: Table/View 'ANIMALS' does not exist.
Line 13, column 1
Execution finished after 0 s, 3 error(s) occurred.
What I would like to know is, is there something wrong with the code in the tutorial or is there a setting somewhere in the set up of mySQL in netbeans that I need to configure to get the code to work?
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
Related
I want to have a JSON column in a table. I want to have (persisted) computed column that extracts useful information from the JSON data.
I want to have a "strict" JSON path but I also want to check that the path exists in the JSON so that the error message is specific to the table and isn't just about the illegal JSON path.
CREATE TABLE DataWithJSON (
DataID BIGINT,
DataJSON NVARCHAR(MAX) CONSTRAINT CK_DataWithJSON_DataJSON CHECK (
ISJSON(DataJSON) = 1
AND JSON_VALUE(DataJSON, 'lax $.Data.ID') IS NOT NULL
),
DataJSONID AS JSON_VALUE(DataJSON, 'strict $.Data.ID') PERSISTED
);
INSERT INTO DataWithJSON (DataID, DataJSON)
VALUES (666, N'{"Data":{"Name":"Tydýt"}}');
This code returns (on my machine) somewhat mysterious error message
Msg 13608, Level 16, State 2, Line xx Property cannot be found on the specified JSON path.
I would like to see more specific message
Msg 547, Level 16, State 0, Line yy The INSERT statement conflicted with the CHECK constraint "CK_DataWithJSON_DataJSON". The conflict occurred in database "DB", table "schema.DataWithJSON", column 'DataJSON'.
Is this possible to achieve just with table constraints or am I out of luck and do I have to check the JSON in a stored procedure/application before inserting to the table?
One solution would be to have "lax" path in the computed column, which, hopefully, is not the only solution. I will fall back to that solution if there is none other to be found.
You can't control the order that check constraints and computed columns are evaluated but you can use a CASE expression in the computed column definition so that the JSON_VALUE(... 'strict ...) part is only evaluated if the check constraint would pass.
CREATE TABLE DataWithJSON (
DataID BIGINT,
DataJSON NVARCHAR(MAX) CONSTRAINT CK_DataWithJSON_DataJSON CHECK (
ISJSON(DataJSON) = 1 AND JSON_VALUE(DataJSON, 'lax $.Data.ID') IS NOT NULL
),
DataJSONID AS CASE WHEN ISJSON(DataJSON) = 1 AND JSON_VALUE(DataJSON, 'lax $.Data.ID') IS NOT NULL THEN JSON_VALUE(DataJSON, 'strict $.Data.ID') END PERSISTED
);
Msg 547, Level 16, State 0, Line 9 The INSERT statement conflicted
with the CHECK constraint "CK_DataWithJSON_DataJSON". The conflict
occurred in database "Foo", table
"dbo.DataWithJSON", column 'DataJSON'. The statement has been
terminated.
On snowflake database, I am trying to run a merge on a table: PK_TABLE_TEST. This table DDL is as below:
CREATE OR REPLACE TABLE "LOAD".pk_table_test (
RESORT STRING NOT NULL,
STAYDATE DATE NOT NULL,
RATE_CODE STRING NOT NULL,
RNS NUMBER (38, 0),
GST NUMBER (38, 0),
REVENUE FLOAT,
REPORT_DATE DATE NOT NULL,
SYS_INS_DATE timestamp,
PRIMARY KEY (RESORT),
UNIQUE(RESORT, STAYDATE, RATE_CODE, REPORT_DATE)
);
I have the same table on my staging database with the name: pk_table_test_stg.
In my store procedure, I formed a merge query by getting all the keys from INFORMATION_SCHEMA. Below is the merge query:
MERGE INTO LOAD.PK_TABLE_TEST target USING LOAD.PK_TABLE_TEST_STG stg ON target.RESORT = stg.RESORT and target.STAYDATE = stg.STAYDATE and target.RATE_CODE = stg.RATE_CODE and target.REPORT_DATE = stg.REPORT_DATE WHEN MATCHED THEN UPDATE SET target.RESORT = stg.RESORT,target.STAYDATE = stg.STAYDATE,target.RATE_CODE = stg.RATE_CODE,target.RNS = stg.RNS,target.GST = stg.GST,target.REVENUE = stg.REVENUE,target.REPORT_DATE = stg.REPORT_DATE,target.SYS_INS_DATE = '2020-10-10 4:35:24'; WHEN NOT MATCHED THEN INSERT (RESORT,STAYDATE,RATE_CODE,RNS,GST,REVENUE,REPORT_DATE,SYS_INS_DATE) VALUES (stg.RESORT,stg.STAYDATE,stg.RATE_CODE,stg.RNS,stg.GST,stg.REVENUE,stg.REPORT_DATE,stg.SYS_INS_DATE);
But when I run the query, it says unexpected WHEN.
SQL Error [1003] [42000]: SQL compilation error:
syntax error line 2 at position 272 unexpected 'WHEN'.
Is there any syntax error with the query I formed ? Is it the right syntax when there are multiple columns in the ON condition ?
Could anyone let me know how can I fix the issue ? Any help is appreciated.
You have a semicolon in your query:
target.SYS_INS_DATE = '2020-10-10 4:35:24'; WHEN NOT MATCHED THEN INSERT
Try to delete this one :-)
More info about the syntax (which looks correct) can be found here: https://docs.snowflake.com/en/sql-reference/sql/merge.html
Have some tables:
CREATE TABLE `asource` (
`id` int(10) unsigned NOT NULL DEFAULT '0'
);
CREATE TABLE `adestination` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`generated` tinyint(1) GENERATED ALWAYS AS (id = 2) STORED NOT NULL
);
I copy a row from asource to adestination:
INSERT INTO adestination
SELECT asource.*
FROM asource;
The above generates an error:
Error Code: 1136. Column count doesn't match value count at row 1
Ok, quite strange to require me to mention generated query. But ok, I add that column to the query:
INSERT INTO adestination
SELECT asource.*, NULL AS `generated`
FROM asource;
This has worked fine in 5.7.10. However, it generates an error in 5.7.11 (due to a fix:
Error Code: 3105. The value specified for generated column 'generated' in table 'adestination' is not allowed.
Ok, next try:
INSERT INTO adestination
SELECT asource.*, 1 AS `generated`
FROM asource;
But still the same error. I have tried 0, TRUE, FALSE but the error persists.
The DEFAULT value which is stated as the only allowed value (specs or docs). However, the following generates a syntax error (DEFAULT is not supported there):
INSERT INTO adestination
SELECT asource.*, DEFAULT AS `generated`
FROM asource;
So, how can I copy a row from one table to another using INSERT INTO ... SELECT if the destination table adds some columns where some of them are GENERATED?
The code calling this query is generic and has no knowledge what columns that particular tables have. It just knows which extra columns the destination table has. The source table is a live table, the destination table is a historical version of the source table. It has few columns extra like user id made the change, what type of the change it is (insert, update, delete) when etc.
Sadly this is just how MySQL works now to "conform to SQL standards".
The only value that the generated column can accept in an update, insert, etc. is DEFAULT, or the other option is to omit the column altogether.
My poor mans work around for these are to just disable the generated column while I'm working with the data (like for importing a dump) and then go back and add the generated column expression afterwards.
You must declare the columns
Insert into adestination (id, generated)
select id, 1
from asource;
It is best practice to list out the columns, and use null as field1 for the auto incremented id field.
INSERT INTO adestination
(id,
field1,
field2)
SELECT
null AS generated,
asource.field1,
asource.field2
FROM asource;
I have found an answer here on how I can specify an AUTO_INCREMENT on a secondary column in a multiple column index in MySQL e.g.
CREATE TABLE foo (
id INTEGER NOT NULL AUTO_INCREMENT,
grp INTEGER NOT NULL ,
name VARCHAR(64),
PRIMARY KEY (id, grp)
) ENGINE = MyISAM;
How would I extend a slick.driver.MySQL.api.Table so that such a table is generated, if indeed it is at all possible? Difficulties I am having currently: (1) I don't know how to create a composite primary key in slick within the main create statement and (2) I don't know how to specify to use the MyISAM engine.
Update: Following #ulas' advice, I used slick.codegen to generate the slick data model from the (already created) SQL table. However, the data model cannot be used to then recreate the table - it generates two statements instead of one, and neither reference MyISAM. Regarding this, I have listed an issue in the slick github repos.
For now this leaves me with following #RickJames' advice, which I would rather do anyway since it doesn't rely on MyISAM, a non-default engine for the current version of MySQL.
So my question can now be collapsed to, how would I execute the following using slick?
BEGIN;
SELECT #id := IFNULL(MAX(id), -1) + 1 FROM foo WHERE grp = 1 FOR UPDATE;
INSERT INTO foo VALUES (#id, 1, 'bar');
COMMIT;
I have no idea how to do it using the 'higher-level' abstraction, so I tried following the Plain SQL Queries section of the slick manual. My attempt went something like:
val statements = DBIO.seq(
sqlu" SELECT #id := IFNULL(MAX(id), -1) + 1 FROM foo WHERE grp = 1 FOR UPDATE",
sqlu"INSERT INTO foo VALUES (#id, 1, 'bar')"
)
db.run(statements.transactionally)
But I got the error:
Exception in thread "main" slick.SlickException: Update statements should not return a ResultSet
Help appreciated.
There are 3 columns (Level, Code, Message) in the output when SHOW ERRORS is executed. Is there any way to select one specific column (lets say, Message) instead of all three.
The main purpose is to get the error message (3rd column) in a variable for further processing.
Edited:
The result of the query SHOW ERRORS after a erroneous select query SELECT anything is like that:
+-------+------+-------------------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------------------+
| Error | 1054 | Unknown column 'anything' in 'field list' |
+-------+------+-------------------------------------------+
I was looking mysql for a mysql equivalent to the T-SQL ##ERROR and came across your question.
I have used GET DIAGNOSTICS to gain access to the error information and then use these as input for inserts to error logs.
Create structures for example:
CREATE TABLE table_that_exists
(
column_that_exists INT(11) NOT NULL
, PRIMARY KEY (column_that_exists)
);
CREATE TABLE tbl_error_log
(
id INT(11) NOT NULL AUTO_INCREMENT
, err_no INT(4)
, err_msg VARCHAR(50)
, source_proc VARCHAR(50)
, PRIMARY KEY (id)
);
Run query to produce an error & show output of SHOW_ERRORS:
SELECT anything FROM table_that_exists;
SHOW ERRORS;
Example of how to access data for use in other procedures/error management:
GET DIAGNOSTICS CONDITION 1
#P1 = MYSQL_ERRNO, #P2 = MESSAGE_TEXT;
SELECT #P1, #P2;
INSERT INTO tbl_error_log (err_no, err_msg, source_proc)
VALUES (#P1, #P2, 'sp_faulty_procedure');
SELECT * FROM tbl_error_log;