Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a code snippet from MYSQL that creates a 2 tables with a constrain between them plus some data to be inserted in one of the tables.
I would like to be converted equivalently to MSSQL. I tried migration but it keeps giving me an error on conversion and i can't figure out where is the problem as on mysql this code works fine.
CREATE TABLE `tbl_variable_types`
(
`variable_type_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`variable_type` varchar(10) DEFAULT NULL,
PRIMARY KEY (`variable_type_id`),
UNIQUE KEY `variable_type_id_UNIQUE` (`variable_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
INSERT INTO `tbl_variable_types` VALUES
(1,'BOOL'),(2,'BYTE'),(3,'WORD'),(4,'DWORD'),
(5,'SINT'),(6,'INT'),(7,'DINT'),(8,'LINT'),(9,'USINT'),(10,'UINT'),
(11,'UDINT'),(12,'ULINT'),(13,'REAL'),(14,'LREAL'),(15,'STRING');
CREATE TABLE `tbl_variables`
(
`variable_tag_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique tag id to be used when calling variable in the code',
`variable_name` varchar(100) NOT NULL COMMENT 'Variable string name from the plc CASE SENSITIVE',
`variable_type` int(11) unsigned NOT NULL COMMENT 'The variable type from the twin table',
PRIMARY KEY (`variable_tag_id`),
UNIQUE KEY `variable_tag_id_UNIQUE` (`variable_tag_id`),
KEY `c_var_type_idx` (`variable_type`),
CONSTRAINT `c_var_type` FOREIGN KEY (`variable_type`)
REFERENCES `tbl_variable_types` (`variable_type_id`)
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
How to translate this code to SQL Server?
Are you looking for below query
CREATE TABLE tbl_variable_types
(
variable_type_id int PRIMARY KEY NOT NULL Identity(1,1),
variable_type varchar(10) DEFAULT NULL
)
INSERT INTO tbl_variable_types VALUES (1,'BOOL'),(2,'BYTE'),(3,'WORD'),(4,'DWORD'),(5,'SINT'),(6,'INT'),
(7,'DINT'),(8,'LINT'),(9,'USINT'),(10,'UINT'),(11,'UDINT'),(12,'ULINT'),(13,'REAL'),
(14,'LREAL'),(15,'STRING');
CREATE TABLE tbl_variables
(
variable_tag_id int NOT NULL IDentity (1,1) PRIMARY KEY ,
variable_name varchar(100) NOT NULL,
variable_type int NOT NULL REFERENCES tbl_variable_types (variable_type_id),
);
For adding Comment of column
EXEC sp_addextendedproperty
#name = N'Description', #value = 'Hey, here is my description!',
#level0type = N'Schema', #level0name = yourschema,
#level1type = N'Table', #level1name = YourTable,
#level2type = N'Column', #level2name = yourColumn;
GO
Related
I currently build a database and write stored procedures for an Android app. I am long time programmer and created some databases years ago, but did not really work with stored procedures until now. The problem that I have at the moment is that I find no right way to check if a given string (specified by stringId) and a given language (specified by languageId) does not exist, and if a translated string already exists before I go on and insert a new translated string into the table TranslatedStrings. I looked up many similar questions and lots of other websites and although some seem to have had the exact same problem their solution did work for them but not for me.
Here is my current Create Procedure script:
create procedure `InsertTranslatedString`(in stringId int(10) unsigned, in translationSource tinyint(3) unsigned, in translationLanguageId int(10) unsigned,
in translatedString mediumtext, out insertedTranslatedStringId int(10) unsigned, out returnValue int(10))
reads sql data
modifies sql data
begin
-- if the string id does not exists
if (select count(1) from `Strings` where `stringId` = stringId) = 0
then
-- return error code
set returnValue = -1;
set insertedTranslatedStringId = 0;
-- if the language id does not exists
elseif (select count(1) from `Languages` where `languageId` = translationLanguageId) = 0
then
-- return error code
set returnValue = -2;
set insertedTranslatedStringId = 0;
-- if the translated string already exists
elseif (select count(1) from `TranslatedStrings` where `stringId` = stringId and `languageId` = translationLanguageId) > 0
then
-- return error code
set returnValue = -3;
set insertedTranslatedStringId = 0;
-- if we are ready to go
else
-- insert the actual translated string
insert into TranslatedStrings (`stringId`, `languageId`, `value`, `translationSource`, `createdDateTime`)
values (stringId, translationLanguageId, translatedString, translationSource, now());
select #newTranslatedStringId := last_insert_id();
-- give back output parameters
set insertedTranslatedStringId = #newTranslatedStringId;
set returnValue = 0;
end if;
end $$
The creation of the procedure works like charm.
I call the procedure with call InsertTranslatedString(76, 0, 1, 'German (Germany)', #insertedTranslatedStringId, #returnValue); Both stringId 76 and languageId 1 do not exist.
When I make this call I notice that the if-elseif-elseif-else block skips the first if (stringId check) even though it should enter its then block. The procedure however enters the first elseif (languageId check) which works fine.
I also tried out if-checks like these: if not exists (select 1 from 'Strings' where 'stringId' = stringId) but there the exists() function seemed to always return true not matter if the select returned a row or no row; the procedure would then skip right through to the second elseif just because I used a elseif exists (select... there. The actual select however does not return any row if I run it separately. Very confusing.
Here are the three referenced tables:
CREATE TABLE `Languages` (
`languageId` int(10) unsigned NOT NULL,
`nameStringId` int(10) unsigned NOT NULL,
`languageCode` varchar(5) DEFAULT NULL,
`hiddenInSettings` tinyint(1) DEFAULT '0',
PRIMARY KEY (`languageId`),
KEY `FK_Languages_nameStringId` (`nameStringId`),
CONSTRAINT `FK_Languages_nameStringId` FOREIGN KEY (`nameStringId`) REFERENCES `Strings` (`stringId`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='contains all supported and automatically translated languages'
CREATE TABLE `Strings` (
`stringId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`originalValue` mediumtext NOT NULL,
`originalLanguageId` int(10) unsigned NOT NULL,
PRIMARY KEY (`stringId`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='contains all language-independent strings instances'
CREATE TABLE `TranslatedStrings` (
`stringId` int(10) unsigned NOT NULL,
`languageId` int(10) unsigned NOT NULL,
`value` mediumtext NOT NULL,
`translationSource` tinyint(3) unsigned DEFAULT '0',
`createdDateTime` datetime DEFAULT NULL,
`lastModifiedDateTime` datetime DEFAULT NULL,
`incorrectTranslationState` tinyint(3) unsigned DEFAULT '0',
`incorrectTranslationReporterId` int(10) unsigned DEFAULT NULL,
`incorrectTranslationReportedDateTime` datetime DEFAULT NULL,
PRIMARY KEY (`stringId`,`languageId`),
KEY `FK_TranslatedStrings_languageId` (`languageId`),
KEY `FK_TranslatedStrings_incorrectTranslationReporterId` (`incorrectTranslationReporterId`),
CONSTRAINT `FK_TranslatedStrings_incorrectTranslationReporterId` FOREIGN KEY (`incorrectTranslationReporterId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE,
CONSTRAINT `FK_TranslatedStrings_languageId` FOREIGN KEY (`languageId`) REFERENCES `Languages` (`languageId`) ON DELETE CASCADE,
CONSTRAINT `FK_TranslatedStrings_stringId` FOREIGN KEY (`stringId`) REFERENCES `Strings` (`stringId`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='contains all localized and automatically translated strings'
When I created the tables I did not create these KEY entries by the way, they were created by MySQL Server. Odd that they only resemble some of the CONSTRAINT entries and not all.
Since Strings only has a single-column primary key and no foreign keys I'm puzzled that its corresponding if-statement isn't triggered. What I am doing wrong?
I am having problems with table locking in my little app and want to know how I can improve my query.
Below is the relevant table information.
| assigned_presents | CREATE TABLE `assigned_presents` (
`id` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`recipient_id` bigint(10) unsigned NOT NULL,
`present_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `recipient_id_index` (`recipient_id`),
KEY `present_id` (`present_id`),
CONSTRAINT `fk_message` FOREIGN KEY (`recipient_id`) REFERENCES `person` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=12914 DEFAULT CHARSET=latin1 |
| present | CREATE TABLE `present` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`description` varchar(100) DEFAULT NULL,
`type_id` int(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `present_type_id` (`present`,`type_id`),
KEY `index_type_id` (`type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=83196627 DEFAULT CHARSET=latin1 |
| person | CREATE TABLE `person` (
`id` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
KEY `added_index` (`added`),
) ENGINE=InnoDB AUTO_INCREMENT=249486846 DEFAULT CHARSET=utf8 |
And this is my current query. It does the job but I'm wondering if it could be improved.
INSERT INTO assigned_presents (present_id, recipient_id)
SELECT present.id, ${person_id} FROM present WHERE present.type_id IN (""" + ${present_type_options} + """)
AND NOT EXISTS (SELECT present_id FROM assigned_presents WHERE assigned_present.present_id=present.id)
ORDER BY present.id LIMIT 1
It is basically assigning a present of a particular type (${present_type_options}) to a person (${person_id}) but making sure that present hasn't already been assigned. I hope it makes sense.
I basically want to insert a present_id and person_id into assigned_presents as long as the present_id doesn't already exist in the table.
The query makes sense to me but I am not an experienced MySQL user. I do see that there may be row locking issues when called under heavy load (I haven't figured out how to stress test it) due to the query relying on two select queries before the insert.
The error I get is:
Deadlock found when trying to get lock; try restarting transaction
Also, I can't retry the query. It HAS to work the first time it is called. The reason for this is that this is a first in first served type API where responses are immediate.
Hope someone can help.
I have got this table:
CREATE TABLE `pertemba_client_raw_data` (
`line_id` int(11) NOT NULL AUTO_INCREMENT,
`feed_id` int(11) NOT NULL COMMENT 'References pertemba_client_feed_log.feed_id',
`data_line` int(11) NOT NULL COMMENT 'Eg. The CSV line number or JSON object index.',
`property_title` varchar(255) NOT NULL COMMENT 'Eg. The CSV header or JSON key.',
`property_value` varchar(255) NOT NULL COMMENT 'Eg. The CSV field value or JSON object value.',
`date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`line_id`),
UNIQUE KEY `pertemba_client_raw_data_line_id_pk` (`line_id`),
KEY `feed_id` (`feed_id`),
CONSTRAINT `pertemba_client_raw_data_ibfk_1` FOREIGN KEY (`feed_id`) REFERENCES `pertemba_client_feed_log` (`feed_id`)
) ENGINE=InnoDB AUTO_INCREMENT=113121 DEFAULT CHARSET=utf8
Which currently contains about 110,000 records, but will become much larger.
I have a php process running against this table that is running very slowly - the run time is currently 10+ minutes. When I repeatedly run show PROCESSLIST; this query in the process is always running:
SELECT COUNT(pcr.line_id) AS result FROM pertemba_client_raw_data AS pcr
WHERE pcr.feed_id = :feedId
AND pcr.property_title = :title
AND pcr.property_value = :optionLink
I would appreciate any optimisations that can be suggested for beating this problem.
First step is to identify the problem. Try
EXPLAIN SELECT COUNT(pcr.line_id) AS result
FROM pertemba_client_raw_data AS pcr
WHERE pcr.feed_id = :feedId
AND pcr.property_title = :title
AND pcr.property_value = :optionLink
For your query, as pointed out by juergen, I believe you can improve performance if you add index to property_title and property_value as composite index such as:
KEY `feed_id` (`feed_id`, `property_title`, `property_value`)
After that, try to execute EXPLAIN again to confirm that performance issue is solved or not.
I'm about to set up a large server that assigns ports to specific objects. Every object is granted a port on creation and the ports can theoretically be assigned for years. If someone destroys their object, the port is released and is up for grabs. If I had a MySQL table containing all objects AND their ports, how would I retrieve a random free port within the range specified?
So:
Table has id and port. Query should select number where between <min> and <max> and not in table. Is anything like this possible in MySQL or would I have to get another table to jump in?
Edit
I currently have the following two tables:
CREATE TABLE `scjs_relays` (
`id` INT(100) UNSIGNED NOT NULL AUTO_INCREMENT,
`displayname` VARCHAR(50) NOT NULL COMMENT 'Name the relay shows up with at the overview',
`origin` VARCHAR(15) NOT NULL COMMENT 'IP the packets originate from',
`auth` BIT(1) NOT NULL DEFAULT b'',
`authurl` VARCHAR(255) NULL DEFAULT '0' COMMENT 'URL to retrieve auth token from',
`authtimeout` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT 'Time before person has to be reauthed',
`steamid` BIT(1) NOT NULL DEFAULT b'',
`teamchat` BIT(1) NOT NULL DEFAULT b'',
`timestamp` BIT(1) NOT NULL DEFAULT b'',
`disconnect` BIT(1) NOT NULL DEFAULT b'',
`playerip` BIT(1) NOT NULL DEFAULT b'',
`node` INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
COMMENT='Chat relays'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `scjs_ports` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`port` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`node` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`relayid` INT(100) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COMMENT='Ports per server'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
However, if I try to add a foreign key I get errors. the id in the scjs_users table is AUTO_INCREMENT because this is going to be an incremental ID, every server will have their own ID that never will be reused. The foreign key I currently have is the following:
ALTER TABLE `scjs_ports`
ADD CONSTRAINT `FK_relayid` FOREIGN KEY (`relayid`) REFERENCES `scjs_relays` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
Should that work fine? If I update the row in scjs_relay, id will never change, only the other columns, so is CASCADE the right option here? And if a row is deleted, it's port is obviously free'd up, so it should be set to NULL.
FOr your application you would probably wantt a single table with all your available ports in it and a reference to the object that has the port (or is null if no object is currently assigned to port)
So that might look like this:
id - autoincrement primary key
port - port number, has unique index
object_id - foreign key reference to object that has port, NULL-able, unique index if needed for reverse object to port lookups
You would need to think about allowing for consistent reads so when you are about to search for open row and assign it an object, you would need to do this within a transaction and with a lock upon first select so no other connection can touch that row while you are trying to update it.
That sequence might look like this:
START TRANSACTION;
SELECT #update_id:=id
FROM table
WHERE object_id IS NULL
ORDER BY port ASC
/*
Note you could order by RAND here if you truly want random
but query would not be optimized
*/
LIMIT 1
FOR UPDATE;
UPDATE table SET object_id = ?
WHERE id = #update_id;
COMMIT;
Here ? is the object reference for object you want to assign to the port. As you can see, this might lend itself well to be a stored procedure, where you pass in the object id as parameter.
I'd implement this by having a table with all the available ports for usage.
Then when issuing a new port I'd check availability by LEFT JOIN this table to the issued ports table like this:
SELECT table1.port from table1 LEFT JOIN table2 on table1.port = table2.port
WHERE table2 is null
LIMIT 1;
I've got a weird problem on a MySQL table. When trying to insert a new row, it says the primary key is duplicate. My primary key is auto incremental and is not set within my query (automatically set by MySQL).
The problem is I get a "Duplicate primary key" error on a key that doesn't even exists (I checked). I solved the problem increasing the current auto_increment value but I can't understand how it happened.
Any help would be great.
Edit
Table creation
CREATE TABLE `articles_mvt` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`ext_article_id` int(5) NOT NULL,
`date_mvt` date NOT NULL,
`qte` float(4,2) NOT NULL,
`in_out` enum('in','out') NOT NULL,
`ext_nateco_id` int(5) NOT NULL,
`ext_agent_id` int(5) NOT NULL COMMENT 'Demandeur',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1647 ;
Problematic query
INSERT INTO articles_mvt (
`ext_article_id`,
`date_mvt`,
`qte`,
`in_out`,
`ext_nateco_id`,
`ext_agent_id`
)
VALUES (
'".$_POST["numArticle"]."',
'".dateSql($_POST["date_mvt"])."',
".$_POST["qte_entier"].".".$_POST["qte_virgule"].",
'".$_POST["in_out"]."',
".$_POST["numNateco"].",
".$_POST["demandeur"]."
)
FYI variables are sanitized earlier in the code ;)
Well i think at that time you did not check auto Inc flag on primary key. So when you try to enter than value 0 is insert in the primary key and for second entry it gives error. like that
ID Value
0 A ok it not give error
0 ff it gives error..
Or you may try to insert a row whose ID is already exist like
ID Value
11 A ok it not give error
11 ff it gives error..