faq / truice
Goto Github
PK
View Code? Open in Web Editor
NEW
18.0
65.0
1.79 MB
Truice is a database editor specifically for Trinity.
Pascal 99.95%
Batchfile 0.05%
truice’s Introduction
Truice is a database editor specifically made for TrinityCore. It is a fork of Quice, which was made for MaNGoS.
You can edit quests, creatures, gameobjects, items, loot, SmartAI (smart_scripts), conditions and some minor things.
It is written in Delphi, source on github compiled using Embarcadero Delphi 10.2.2 (Tokyo) and the source is available under https://github.com/Faq/Truice
and precompiled binaries under https://github.com/Faq/Truice/releases
How To run:
- choose 32 bit or 64 and copy «libmysql.dll» and «Truice.exe» outside folder (where are all other folders: CSV, Lang etc.);
- run «Truice.exe»
- dll files are from MySQL v5.7.23
- if You got it right, then it should be like this:
To compile use:
Delphi XE2+ (there is Community Edition of Delphi what is completely free https://www.embarcadero.com/products/delphi/starter)
and these additional components:
A) JEDI Visual Component Library 3.5
http://jvcl.delphi-jedi.org/
http://jvcl.sourceforge.net/daily/
http://github.com/project-jedi/jvcl
B) JEDI Code Library 2.9
http://sourceforge.net/projects/jcl/
http://jcl.sourceforge.net/daily/
http://github.com/project-jedi/jcl
C) Droping ZeosLib to use Delphi internal db component FireDAC (from 22.08.2018).
ZeosDBO 7.3 from testing branch (SVN rev4068) (last commit with ZeosLib https://github.com/Faq/Truice/commit/3e74ac4aececd7b4c55b607ca9c3b63eb85f3a17)
http://sourceforge.net/projects/zeoslib/ (new link)
http://svn.code.sf.net/p/zeoslib/code-0
Original topic on TC forum:
https://community.trinitycore.org/topic/13899-truice-2018-win32/
Truice Download:
https://github.com/Faq/Truice/releases
Author: Faq
truice’s People
Contributors
truice’s Issues
Implement SMART_TARGET_CLOSEST_ENEMY (25)
Please
Please upload latest compiled version, thanks for your time.
support for MySQL 5.5
I can only think of the version differences from MySQL 5.0/5.1 to MySQL 5.5 as being the problem of the error message that I get when trying to log in to the server.
Unknown mysql server at localhost:3306
replacing libmysql.dll with the one from the new version gives me error messages of missing libmysql50.dll and other files.
Quest tab error
When you go to Quest tab, you get an error saying SQL Error, unknown column ‘entry’ in ‘where clause’
Error on quest creating button ‘New Quest»
precompied Version
Many thanks for this fix can you give us a precompiled version too please.
Thank you very much.
Quest Tab
I can search now but i i choose the quest it tells me:
Unknow column ‘entry’ in where clause.
Thanks for help, fixing and for you nice work
NPCFlags.csv values update
Based on http://www.trinitycore.info/Creature_template_tc2#npcflag
0;Gossip
1;Quest Giver
2;UNK1
3;UNK2
4;Trainer
5;Class Trainer
6;Profession Trainer
7;Vendor
8;Vendor Ammo
9;Vendor Food
10;Vendor Poison
11;Vendor Reagent
12;Repairer
13;Flight Master
14;Spirit Healer
15;Spirit Guide
16;Innkeeper
17;Banker
18;Petitioner
19;Tabard Designer
20;Battlemaster
21;Auctioneer
22;Stable Master
23;Guild Banker
24;Spellclick
25;UNK3 (PLAYER_VEHICLE?) (players with mounts that have vehicle data should have it set)
26;Mailbox
27;UNK4 (OUTDOORPVP?)
[Feature] Removed table quest_start_scripts and StartScript from table quest_template
[Feature] Add CONDITION_GENDER to Conditions
[Feature] Add to item_template UI item_template.flagsCustom field
[Feature RQ] Add default tables to connect to mysql interface
Currently the first time you run Truice you can’t get the correct table names from DB until you enter them manually (don’t remember if you have to connect the first time or just enter the names). So I suggest to populate the login interface with the default values leaving only the password field empty.
P.S. Don’t waste time on it if it isn’t easy to do.
equipment_id depreciated
The equipment_id field in the creature_template has been moved over to its own table: creature_equip_template. Because of this, loading a creature in Truice results in an error.
Additionally, the «Creature Location» tab is not loading spawns correctly. Possibly due to this SQL error? Not entirely sure.
Drop support for SMART_ACTION_SEND_CASTCREATUREORGO
Need to add new QuestFlags for cataclysm
Implement SMART_ACTION_SET_POWER, SMART_ACTION_ADD_POWE…
Still cannot connect Truice 1.39
Hi there, I check out this post
#30
And this one
#31
And i am still not able to connect truice to my database.
Error: Unknown MySQL server host ‘localhost’ (11001)
Trinity compile server works, I can connect to db with Heidisql, I have I have MV C++ 2010, and NET Framework 4.5. I had my server running in an old computer (windows 7 64 bit) and was moving everything to this new one (wich sadly has Windows 8 64 bits). And I get everything working except Truice. I have tried to filling manually in the db the server name, root and tried changing the pasword (in the mysql tab in DB with heidisql). Then restarting copy pasting pasword username… and nothing…
I am new to all this, and have been using with no problem truice in the past (1.37) can anyone help me here?
Thanks!
Truice 1.3.6 Quest Error
[BUG] Other > Game Events
- Searching by Entry returns error (probably field name need to be changed from
Entry
toeventEntry
). - When a field is updated the Description text is displayed under the holiday tab which disappears.
SAI_CastFlags.csv values update
Rename _questrelation tables to _queststarter and _involve… …drelation to _questender, for creature and gameobject
GameObjectFlags.csv values update
Based on http://www.trinitycore.info/Gameobject_template_tc2#flags
0;IN_USE (Disables interaction while being animated)
1;LOCKED (Requires a key, spell, or event to be opened)
2;INTERACT_COND (Untargetable, cannot interact)
3;TRANSPORT (GO can transport - boat, elevator, car)
4;NOT_SELECTABLE (Not even in GM-mode)
5;NODESPAWN (Typically for doors, they just change state)
6;DAMAGED (GO has been siege damaged)
7;DESTROYED (GO has been destroyed)
P.S. Is there a way to verify that TRIGGERED isn’t used in TC for GO’s?
Links for donwload are old.
I try download precompiled 1.3.9 and links are broken
Broken searching in locales Truice 1.3.8
Configure truice to use localization file (ctrl+F3)
Set Language Russian(not needed), !!!-> Locales set to _loc8 <-!!!
Use search tab (any: quest, go, creatures)
type name of what you want on Ru language — empty string (db has ru (loc8) locale filled in locales tables)
PS: truice 1.3.7 from this repo — all is fine
[Feature] Conditions
Bug generating SQL Gameobgect changes
With latest updates there is a bug, if you try to change some values of GO on main tab or spawn tab and press Button to have SQL generated you will be at empty screen
Something important was deleted from MainUnit.dfm in 257e6f0
[FIX] QuestFlags.csv
http://www.trinitycore.info/Quest_template_tc2#Flags
1;STAY_ALIVE
2;PARTY_ACCEPT
3;EXPLORATION
4;SHARABLE
5;NONE2 (Unknown)
6;EPIC
7;RAID
8;TBC
9;DELIVER_MORE
10;HIDDEN_REWARDS
11;AUTO_REWARDED
12;TBC_RACES
13;DAILY
14;REPEATABLE
15;UNAVAILABLE
16;WEEKLY
17;AUTOCOMPLETE
18;SPECIAL_ITEM
19;OBJ_TEXT
20;AUTO_ACCEPT
SpawnMaskFlags.csv values update
Based on http://www.trinitycore.info/Creature_tc2#spawnMask
0;10-man-normal (maps without heroic mode)
1;25-man-normal (heroics pre 3.2)
2;10-man heroic
3;25-man-heroic
P.S. A bit-mask field that can’t have «0;Normal spawn» value and «15;spawned in all versions of maps» is the combination of all previous values (probably left from the time it wasn’t a bit-mask field).
First time connection
Hey,
I have problem in windows 8 with Truice. but Quice works fine
I got this error
SQL Error : Unknown MySQL server host ‘localhost’ (11001)
HoverHeight Table
Missing HoverHeight Table in Truice
[UI] CreatureTemplate>MovmentType
The button drop-dawn menu dimensions needs to be corrected.
ItemExtendedCost.csv is quite old
Hi Faq and good job with continuing with Truice, I really appreciate this tool.
You probably already know but the extended cost ids of this file are missing all cataclysm entries, anyways I could replace the csv file with Quice one, but still doesn’t convince me that it’s flawless, some entries don’t match. I hope it can be solved soon.
lq.entry SQL Error
SQL Error: Unknown column ‘lq.entry’ in ‘on clause’
[Feature] Characters / Account tab
Hey,
what you think add two tab for select characters or account table for manage this tables
i mean add gold or ban account and etc…
plz add
Not Add Truice.exe
SkillLine.csv values update
0;None
6;Frost
8;Fire
26;Arms
38;Combat
39;Subtlety
43;Swords
44;Axes
45;Bows
46;Guns
50;Beast Mastery
51;Survival
54;Maces
55;Two-Handed Swords
56;Holy
78;Shadow Magic
95;Defense
98;Language: Common
101;Dwarven Racial
109;Language: Orcish
111;Language: Dwarven
113;Language: Darnassian
115;Language: Taurahe
118;Dual Wield
124;Tauren Racial
125;Orc Racial
126;Night Elf Racial
129;First Aid
134;Feral Combat
136;Staves
137;Language: Thalassian
138;Language: Draconic
139;Language: Demon Tongue
140;Language: Titan
141;Language: Old Tongue
142;Survival
148;Horse Riding
149;Wolf Riding
150;Tiger Riding
152;Ram Riding
155;Swimming
160;Two-Handed Maces
162;Unarmed
163;Marksmanship
164;Blacksmithing
165;Leatherworking
171;Alchemy
172;Two-Handed Axes
173;Daggers
176;Thrown
182;Herbalism
183;GENERIC (DND)
184;Retribution
185;Cooking
186;Mining
188;Pet - Imp
189;Pet - Felhunter
197;Tailoring
202;Engineering
203;Pet - Spider
204;Pet - Voidwalker
205;Pet - Succubus
206;Pet - Infernal
207;Pet - Doomguard
208;Pet - Wolf
209;Pet - Cat
210;Pet - Bear
211;Pet - Boar
212;Pet - Crocolisk
213;Pet - Carrion Bird
214;Pet - Crab
215;Pet - Gorilla
217;Pet - Raptor
218;Pet - Tallstrider
220;Racial - Undead
226;Crossbows
228;Wands
229;Polearms
236;Pet - Scorpid
237;Arcane
251;Pet - Turtle
253;Assassination
256;Fury
257;Protection
267;Protection
270;Pet - Generic Hunter
293;Plate Mail
313;Language: Gnomish
315;Language: Troll
333;Enchanting
354;Demonology
355;Affliction
356;Fishing
373;Enhancement
374;Restoration
375;Elemental Combat
393;Skinning
413;Mail
414;Leather
415;Cloth
433;Shield
473;Fist Weapons
533;Raptor Riding
553;Mechanostrider Piloting
554;Undead Horsemanship
573;Restoration
574;Balance
593;Destruction
594;Holy
613;Discipline
633;Lockpicking
653;Pet - Bat
654;Pet - Hyena
655;Pet - Bird of Prey
656;Pet - Wind Serpent
673;Language: Gutterspeak
713;Kodo Riding
733;Racial - Troll
753;Racial - Gnome
754;Racial - Human
755;Jewelcrafting
756;Blood Elf Racial
758;Pet - Event - Remote Control
759;Language: Draenei
760;Draenei Racial
761;Pet - Felguard
762;Riding
763;Pet - Dragonhawk
764;Pet - Nether Ray
765;Pet - Sporebat
766;Pet - Warp Stalker
767;Pet - Ravager
768;Pet - Serpent
769;Internal
770;DK Blood
771;DK Frost
772;DK Unholy
773;Inscription
775;Pet - Moth
776;Runeforging
777;Mounts
778;Companions
780;Pet - Exotic Chimaera
781;Pet - Exotic Devlisaur
782;Pet - Ghoul
783;Pet - Exotic Silithid
784;Pet - Exotic Worm
785;Pet - Wasp
786;Pet - Exotic Rhino
787;Pet - Exotic Core Hound
788;Pet - Exotic Spirit Beast
P.S. The changes are correcting DBC errors.
[Feature] Creature Template.flags_extra
It’ll be nice if you can convert the flags_extra field in Creature Template to bit-mask field.
CreatureFlags_extra.csv:
1;INSTANCE_BIND (creature kill binds instance to killer and killer's group)
2;CIVILIAN (creature does not aggro - ignore faction/reputation hostility)
3;NO_PARRY (creature does not parry)
4;NO_PARRY_HASTEN (creature does not counter-attack at parry)
5;NO_BLOCK (creature does not block)
6;NO_CRUSH (creature does not do crush-attacks)
7;NO_XP_AT_KILL (creature kill does not give XP)
8;TRIGGER (creature is trigger-NPC - invisible to players only)
9;NO_TAUNT (creature is immune to taunt-auras and "attack me"-effects)
10;UNK1
11;UNK2
12;UNK3
13;UNK4
14;UNK5
15;WORLDEVENT (custom flag for world events - left room for merging)
16;GUARD (creature is a guard - will ignore feign death and vanish)
17;UNK6
18;NO_CRIT (creature does not do critical strikes)
19;NO_SKILLGAIN (creature won't increase weapon skills)
20;TAUNT_DIMINISH (creature taunt is subject to diminishing returns)
21;ALL_DIMINISH (Creature is subject to all diminishing returns)
22;DUNGEON_BOSS (Creature is a dungeon boss. This flag is generically set by core during runtime. Setting this in database will give you startup error.)
http://www.trinitycore.info/Creature_template_tc2#flags_extra
[Feature RQ] SQL code generation
If possible can you make Truice use « instead of ‘ for the text fields in the SQL code it generates and replace the spaces between the field names (‘, ‘ to ‘,’).
Update SAI to current
SAI_ActionType.csv:
0;SMART_ACTION_NONE
1;SMART_ACTION_TALK
2;SMART_ACTION_SET_FACTION
3;SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL
4;SMART_ACTION_SOUND
5;SMART_ACTION_PLAY_EMOTE
6;SMART_ACTION_FAIL_QUEST
7;SMART_ACTION_ADD_QUEST
8;SMART_ACTION_SET_REACT_STATE
9;SMART_ACTION_ACTIVATE_GOBJECT
10;SMART_ACTION_RANDOM_EMOTE
11;SMART_ACTION_CAST
12;SMART_ACTION_SUMMON_CREATURE
13;SMART_ACTION_THREAT_SINGLE_PCT
14;SMART_ACTION_THREAT_ALL_PCT
15;SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS
16;SMART_ACTION_SEND_CASTCREATUREORGO
17;SMART_ACTION_SET_EMOTE_STATE
18;SMART_ACTION_SET_UNIT_FLAG
19;SMART_ACTION_REMOVE_UNIT_FLAG
20;SMART_ACTION_AUTO_ATTACK
21;SMART_ACTION_ALLOW_COMBAT_MOVEMENT
22;SMART_ACTION_SET_EVENT_PHASE
23;SMART_ACTION_INC_EVENT_PHASE
24;SMART_ACTION_EVADE
25;SMART_ACTION_FLEE_FOR_ASSIST
26;SMART_ACTION_CALL_GROUPEVENTHAPPENS
27;SMART_ACTION_CALL_CASTEDCREATUREORGO
28;SMART_ACTION_REMOVEAURASFROMSPELL
29;SMART_ACTION_FOLLOW
30;SMART_ACTION_RANDOM_PHASE
31;SMART_ACTION_RANDOM_PHASE_RANGE
32;SMART_ACTION_RESET_GOBJECT
33;SMART_ACTION_CALL_KILLEDMONSTER
34;SMART_ACTION_SET_INST_DATA
35;SMART_ACTION_SET_INST_DATA64
36;SMART_ACTION_UPDATE_TEMPLATE
37;SMART_ACTION_DIE
38;SMART_ACTION_SET_IN_COMBAT_WITH_ZONE
39;SMART_ACTION_CALL_FOR_HELP
40;SMART_ACTION_SET_SHEATH
41;SMART_ACTION_FORCE_DESPAWN
42;SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL
43;SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL
44;SMART_ACTION_SET_INGAME_PHASE_MASK
45;SMART_ACTION_SET_DATA
46;SMART_ACTION_MOVE_FORWARD
47;SMART_ACTION_SET_VISIBILITY
48;SMART_ACTION_SET_ACTIVE
49;SMART_ACTION_ATTACK_START
50;SMART_ACTION_SUMMON_GO
51;SMART_ACTION_KILL_UNIT
52;SMART_ACTION_ACTIVATE_TAXI
53;SMART_ACTION_WP_START
54;SMART_ACTION_WP_PAUSE
55;SMART_ACTION_WP_STOP
56;SMART_ACTION_ADD_ITEM
57;SMART_ACTION_REMOVE_ITEM
58;SMART_ACTION_INSTALL_AI_TEMPLATE
59;SMART_ACTION_SET_RUN
60;SMART_ACTION_SET_FLY
61;SMART_ACTION_SET_SWIMM
62;SMART_ACTION_TELEPORT
63;SMART_ACTION_STORE_VARIABLE_DECIMAL
64;SMART_ACTION_STORE_TARGET_LIST
65;SMART_ACTION_WP_RESUME
66;SMART_ACTION_SET_ORIENTATION
67;SMART_ACTION_CREATE_TIMED_EVENT
68;SMART_ACTION_PLAYMOVIE
69;SMART_ACTION_MOVE_TO_POS
70;SMART_ACTION_RESPAWN_TARGET
71;SMART_ACTION_EQUIP
72;SMART_ACTION_CLOSE_GOSSIP
73;SMART_ACTION_TRIGGER_TIMED_EVENT
74;SMART_ACTION_REMOVE_TIMED_EVENT
75;SMART_ACTION_ADD_AURA
76;SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT
77;SMART_ACTION_RESET_SCRIPT_BASE_OBJECT
78;SMART_ACTION_CALL_SCRIPT_RESET
79;SMART_ACTION_SET_RANGED_MOVEMENT
80;SMART_ACTION_CALL_TIMED_ACTIONLIST
81;SMART_ACTION_SET_NPC_FLAG
82;SMART_ACTION_ADD_NPC_FLAG
83;SMART_ACTION_REMOVE_NPC_FLAG
84;SMART_ACTION_SIMPLE_TALK
85;SMART_ACTION_INVOKER_CAST
86;SMART_ACTION_CROSS_CAST
87;SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST
88;SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST
89;SMART_ACTION_RANDOM_MOVE
90;SMART_ACTION_SET_UNIT_FIELD_BYTES_1
91;SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1
92;SMART_ACTION_INTERRUPT_SPELL
93;SMART_ACTION_SEND_GO_CUSTOM_ANIM
94;SMART_ACTION_SET_DYNAMIC_FLAG
95;SMART_ACTION_ADD_DYNAMIC_FLAG
96;SMART_ACTION_REMOVE_DYNAMIC_FLAG
97;SMART_ACTION_JUMP_TO_POS
98;SMART_ACTION_SEND_GOSSIP_MENU
99;SMART_ACTION_GO_SET_LOOT_STATE
100;SMART_ACTION_SEND_TARGET_TO_TARGET
[Feature] Add equipment_id field in Creature Location tab and SQL code generated from it
CSV corections
Emotes.csv
-373;STAND_STATE_SUBMERGED
+373;STATE_SUBMERGED
-429;STATE_SUBMERGED
+429;STATE_SUBMERGED_NEW
Faction.csv probably contains the information from the wrong DBC file.
GameObjectFlags.csv:
0;IN_USE (Disables interaction while being animated)
1;LOCKED (Requires a key, spell, or event to be opened)
2;INTERACT_COND (Untargetable, cannot interact)
3;TRANSPORT (Object can transport - boat, elevator, car)
4;NOT_SELECTABLE (Not even in GM-mode)
5;NODESPAWN (Typically for doors, they just change state)
6;DAMAGED (has been siege damaged)
7;DESTROYED (has been destroyed)
9;DAMAGED?
10;DESTROYED?
ItemExtendedCost.csv:
Languages.csv:
NPCFlags.csv:
-25;PLAYER_VEHICLE
+25;UNK3 (PLAYER_VEHICLE?)
+26;Mailbox (GUARD)
+27;UNK4 (OUTDOORPVP?)
In SAI_EventType.csv there is ; at the end of each line.
SkillLine.csv
0;NONE
6;Frost
8;Fire
26;Arms
38;Combat
39;Subtlety
43;Swords
44;Axes
45;Bows
46;Guns
50;Beast Mastery
51;Survival
54;Maces
55;Two-Handed Swords
56;Holy
78;Shadow Magic
95;Defense
98;Language: Common
101;Dwarven Racial
109;Language: Orcish
111;Language: Dwarven
113;Language: Darnassian
115;Language: Taurahe
118;Dual Wield
124;Tauren Racial
125;Orc Racial
126;Night Elf Racial
129;First Aid
134;Feral Combat
136;Staves
137;Language: Thalassian
138;Language: Draconic
139;Language: Demon Tongue
140;Language: Titan
141;Language: Old Tongue
142;Survival
148;Horse Riding
149;Wolf Riding
150;Tiger Riding
152;Ram Riding
155;Swimming
160;Two-Handed Maces
162;Unarmed
163;Marksmanship
164;Blacksmithing
165;Leatherworking
171;Alchemy
172;Two-Handed Axes
173;Daggers
176;Thrown
182;Herbalism
183;GENERIC (DND)
184;Retribution
185;Cooking
186;Mining
188;Pet - Imp
189;Pet - Felhunter
197;Tailoring
202;Engineering
203;Pet - Spider
204;Pet - Voidwalker
205;Pet - Succubus
206;Pet - Infernal
207;Pet - Doomguard
208;Pet - Wolf
209;Pet - Cat
210;Pet - Bear
211;Pet - Boar
212;Pet - Crocolisk
213;Pet - Carrion Bird
214;Pet - Crab
215;Pet - Gorilla
217;Pet - Raptor
218;Pet - Tallstrider
220;Racial - Undead
226;Crossbows
228;Wands
229;Polearms
236;Pet - Scorpid
237;Arcane
251;Pet - Turtle
253;Assassination
256;Fury
257;Protection
267;Protection
270;Pet - Generic Hunter
293;Plate Mail
313;Language: Gnomish
315;Language: Troll
333;Enchanting
354;Demonology
355;Affliction
356;Fishing
373;Enhancement
374;Restoration
375;Elemental Combat
393;Skinning
413;Mail
414;Leather
415;Cloth
433;Shield
473;Fist Weapons
533;Raptor Riding
553;Mechanostrider Piloting
554;Undead Horsemanship
573;Restoration
574;Balance
593;Destruction
594;Holy
613;Discipline
633;Lockpicking
653;Pet - Bat
654;Pet - Hyena
655;Pet - Bird of Prey
656;Pet - Wind Serpent
673;Language: Gutterspeak
713;Kodo Riding
733;Racial - Troll
753;Racial - Gnome
754;Racial - Human
755;Jewelcrafting
756;Blood Elf Racial
758;Pet - Event - Remote Control
759;Language: Draenei
760;Draenei Racial
761;Pet - Felguard
762;Riding
763;Pet - Dragonhawk
764;Pet - Nether Ray
765;Pet - Sporebat
766;Pet - Warp Stalker
767;Pet - Ravager
768;Pet - Serpent
769;Internal
770;DK Blood
771;DK Frost
772;DK Unholy
773;Inscription
775;Pet - Moth
776;Runeforging
777;Mounts
778;Companions
780;Pet - Exotic Chimaera
781;Pet - Exotic Devlisaur
782;Pet - Ghoul
783;Pet - Exotic Silithid
784;Pet - Exotic Worm
785;Pet - Wasp
786;Pet - Exotic Rhino
787;Pet - Exotic Core Hound
788;Pet - Exotic Spirit Beast
CreatureInhabitType.csv values update
Default.lng
There are a few extra symbols at the end of Default.lng file that probably aren’t needed.
error on closing
locales_quest
locales_quest table now have id
instead of entry
column
Editing locales — empty screen
[UI] Creature/GO>Involved in>Category column
sql error : Table ‘world.creature_queststarter’
SQL Error messages
When I try to look up a quest in the search tab, I get this message:
SQL Error: Unknown column lq.entry
in on clause
I have the latest version so not sure if its something I am doing wrong or what. Please let me know. I like this program and would like to help if I can.
«Gameobject_scripts» is no longer existing
As of Commit #9394dc1 from TrinityCore, Gameobjects_scripts is no longer existing. Thus, you can find a frequent error displaying whenever you look a gameobject up. This is a mediocre problem, as you can still edit gameobjects (1.3.5 works, didn’t test 1.3.6 yet), but it may be worth to check it.
Rank.csv values update
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
-
Different languages
Updated 8 months ago
-
Truice English
Updated a year agoComments count1
-
The program after 1 save to the database breaks.
Updated a year ago
-
Language option not working
Closed 2 years agoComments count1
-
SQL Error: Table ‘world.locales_creature’ doesn’t exist.
Updated 2 years ago
-
Inoperative version 2.1.6 on windows 7
Updated 2 years agoComments count4
-
Will truice be updated to database version 5.7?
Updated 2 years agoComments count9
-
DBedit
Updated 3 years agoComments count1
-
Truice miss/ignore to add some fields into final SQL query.
Updated 2 years agoComments count7
-
Show creature template script is empty
Closed 3 years agoComments count1
-
Cannot load vendor library
Closed 3 years agoComments count3
-
Truice for AzerothCore
Updated 4 years agoComments count2
-
Implement recent table changes
Closed 4 years agoComments count1
-
Can you add Support for Oregoncore 2.4.3 ?
Closed 4 years agoComments count1
-
creature_equip_template
Closed 4 years agoComments count1
-
translate Truice
Closed 4 years agoComments count2
-
SmartAI result missing script entries related to SAI calling the script
Closed 4 years agoComments count3
-
Quest tab error
Closed 4 years agoComments count8
-
Checkbox forms
Closed 4 years agoComments count1
-
Creature_text editing
Closed 4 years agoComments count4
-
Empty forms
Closed 4 years agoComments count9
-
Add a 4th target parameter to SAI
Closed 4 years ago
-
new Spell tab
Updated 4 years ago
-
SAI comment generator
Updated 3 years agoComments count3
-
UI: Searcher not working
Closed 4 years agoComments count9
-
missing spell_school_immune_mask
Closed 4 years ago
-
Window resize
Closed 4 years ago
-
Missing changes
Closed 4 years agoComments count2
-
Redefined action SMART_ACTION_STOP_MOTION -> SMART_ACTION_REMOVE_MOVEMENT
Closed 5 years agoComments count1
-
Dynamic Libraries?
Closed 5 years agoComments count2
-
Please add needed .dll’s for this app
Closed 5 years agoComments count3
-
error connect mysql
Closed 5 years agoComments count1
-
Application hangs
Closed 5 years agoComments count2
-
Truice can’t generate locales
Closed 5 years agoComments count2
-
OfferRewardText & RequestItemText
Closed 5 years agoComments count8
-
Truice Not Reachable
Closed 6 years agoComments count1
-
Truice fix
Closed 6 years agoComments count1
-
Faction H & Faction A
Closed 6 years agoComments count1
-
Creature EAI
Closed 9 years agoComments count4
-
sql error : Table ‘world.creature_queststarter’
Closed 9 years agoComments count2
-
Still cannot connect Truice 1.39
Closed 9 years agoComments count3
-
Links for donwload are old.
Closed 9 years agoComments count1
-
plz add
Closed 9 years agoComments count1
-
Broken searching in locales Truice 1.3.8
Closed 9 years agoComments count14
-
Drop support for SMART_ACTION_SEND_CASTCREATUREORGO
Closed 9 years ago
-
Implement SMART_ACTION_SET_POWER, SMART_ACTION_ADD_POWE…
Closed 9 years ago
-
Implement SMART_TARGET_CLOSEST_ENEMY (25)
Closed 9 years ago
-
Rename _questrelation tables to _queststarter and _involve… …drelation to _questender, for creature and gameobject
Closed 9 years ago
-
Bug generating SQL Gameobgect changes
Closed 9 years agoComments count3
-
Error on quest creating button ‘New Quest»
Closed 9 years ago
Next
Hello.
I have problems with my WorldServer and my database.
When I run it, it gives me an error message like this
Using configuration file /home/trinity/server/etc/worldserver.conf.
Using SSL version: OpenSSL 1.0.1e 11 Feb 2013 (library: OpenSSL 1.0.1e 11 Feb 2013)
Using ACE version: 5.8.3
TrinityCore rev. db848f204538 2013-10-12 13:41:00 +0200 (master branch) (Unix, Release) (worldserver-daemon)
<Ctrl-C> to stop.
______ __
/__ _ __ __/ __
/_/ / _ __ /_ ___ /_ , _ __ __
/`’__/ /’ _ `/ / / /
/ / / _ _
_ _ _ _ _ _ __/`____
/_//_/ /_//_//_//_//__/ `/___/>
C O R E /___/
In mysql_stmt_prepare() id: 55, sql: «SELECT name, permission, help FROM command»
Unknown column ‘permission’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘unit_flags2’ in ‘field list’
DatabasePool world NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile for specific errors.
Cannot connect to world database 127.0.0.1;3306;XXX;XXX;world
In mysql_stmt_prepare() id: 55, sql: «SELECT name, permission, help FROM command»
Unknown column ‘permission’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 55, sql: «SELECT name, permission, help FROM command»
Unknown column ‘permission’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘trainer_spell’ in ‘field list’
In mysql_stmt_prepare() id: 55, sql: «SELECT name, permission, help FROM command»
Unknown column ‘permission’ in ‘field list’
In mysql_stmt_prepare() id: 56, sql: «SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?»
Unknown column ‘unit_flags2’ in ‘field list’
I’m linux Unbuntu, I have a 3.3.5 version of trinity.
Sorry, I do not speak English very well, so I use a translator.
I tryed all TDB present in the Download tab, and I can get a message similar loan on spa time.
Thank you in advance.
mysql master-slave replication, often encounter errors and lead to slave end replication interruption, this time generally requires manual intervention, skip errors to continue
There are two ways to skip errors:
1.1 Skip a specified number of transactions:
mysql>stop slave; mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; #Skip a transaction mysql>start slave;
1.2 Modify mysql configuration file to skip all errors or specified types of errors through the slave_skip_errors parameter
vi /etc/my.cnf [mysqld] #slave-skip-errors=1062,1053,1146 #Skip the error of the specified error no type #slave-skip-errors=all #Skip all errors
2 cases
Let’s simulate an error scenario
Environment (a configured master-slave replication environment)
master database IP: 192.168.247.128
Slve database IP: 192.168.247.130
mysql version: 5.6.14
binlog-do-db = mydb
Execute the following statement on master:
mysql>use mysql; mysql>create table t1 (id int); mysql>use mydb; mysql>insert into mysql.t1 select 1;
View replication status on slave
mysql> show slave status G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.247.128 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000017 Read_Master_Log_Pos: 2341 Relay_Log_File: DBtest1-relay-bin.000011 Relay_Log_Pos: 494 Relay_Master_Log_File: mysql-bin.000017 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1146 Last_Error: Error 'Table 'mysql.t1' doesn't exist' on query. Default database: 'mydb'. Query: 'insert into mysql.t1 select 1' Skip_Counter: 0 Exec_Master_Log_Pos: 1919 Relay_Log_Space: 1254 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1146 Last_SQL_Error: Error 'Table 'mysql.t1' doesn't exist' on query. Default database: 'mydb'. Query: 'insert into mysql.t1 select 1' Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: f0f7faf6-51a8-11e3-9759-000c29eed3ea Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 131210 21:37:19 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.00 sec)
As can be seen from the results, Read_Master_Log_Pos: 2341, Exec_Master_Log_Pos: 1919 error Last_SQL_Error: Error’Table’mysql.t1’does’t exist’ on query.
Because only binlog is recorded for mydb, errors occur when tables in other databases are operated on the mydb library but do not exist on slave.
Let’s look at the transaction content in the binlog, where a row represents a transaction.
mysql> SHOW BINLOG EVENTS in 'mysql-bin.000017' from 1919G *************************** 1. row *************************** Log_name: mysql-bin.000017 Pos: 1919 Event_type: Query Server_id: 1 End_log_pos: 1999 Info: BEGIN *************************** 2. row *************************** Log_name: mysql-bin.000017 Pos: 1999 Event_type: Query Server_id: 1 End_log_pos: 2103 Info: use `mydb`; insert into mysql.t1 select 1 *************************** 3. row *************************** Log_name: mysql-bin.000017 Pos: 2103 Event_type: Xid Server_id: 1 End_log_pos: 2134 Info: COMMIT /* xid=106 */ *************************** 4. row *************************** Log_name: mysql-bin.000017 Pos: 2134 Event_type: Query Server_id: 1 End_log_pos: 2213 Info: BEGIN *************************** 5. row *************************** Log_name: mysql-bin.000017 Pos: 2213 Event_type: Query Server_id: 1 End_log_pos: 2310 Info: use `mydb`; insert into t1 select 9 *************************** 6. row *************************** Log_name: mysql-bin.000017 Pos: 2310 Event_type: Xid Server_id: 1 End_log_pos: 2341 Info: COMMIT /* xid=107 */ 6 rows in set (0.00 sec)
From the above results, we need to skip two transactions (Pos: 1999 insert, Pos: 2103 commit)
Skip operation:
mysql>stop slave; mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; Skip a transaction mysql>start slave; mysql> show slave statusG ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 3 Current database: mydb *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.247.128 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000017 Read_Master_Log_Pos: 3613 Relay_Log_File: DBtest1-relay-bin.000018 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000017 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 3613 Relay_Log_Space: 458 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: f0f7faf6-51a8-11e3-9759-000c29eed3ea Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.01 sec)
The replication status is normal.
Время прочтения
16 мин
Просмотры 35K
Привет, Хабр! Представляю вашему вниманию перевод статьи «Error and Transaction Handling in SQL Server. Part One – Jumpstart Error Handling» автора Erland Sommarskog.
1. Введение
Эта статья – первая в серии из трёх статей, посвященных обработке ошибок и транзакций в SQL Server. Её цель – дать вам быстрый старт в теме обработки ошибок, показав базовый пример, который подходит для большей части вашего кода. Эта часть написана в расчете на неопытного читателя, и по этой причине я намеренно умалчиваю о многих деталях. В данный момент задача состоит в том, чтобы рассказать как без упора на почему. Если вы принимаете мои слова на веру, вы можете прочесть только эту часть и отложить остальные две для дальнейших этапов в вашей карьере.
С другой стороны, если вы ставите под сомнение мои рекомендации, вам определенно необходимо прочитать две остальные части, где я погружаюсь в детали намного более глубоко, исследуя очень запутанный мир обработки ошибок и транзакций в SQL Server. Вторая и третья части, так же, как и три приложения, предназначены для читателей с более глубоким опытом. Первая статья — короткая, вторая и третья значительно длиннее.
Все статьи описывают обработку ошибок и транзакций в SQL Server для версии 2005 и более поздних версий.
1.1 Зачем нужна обработка ошибок?
Почему мы обрабатываем ошибки в нашем коде? На это есть много причин. Например, на формах в приложении мы проверяем введенные данные и информируем пользователей о допущенных при вводе ошибках. Ошибки пользователя – это предвиденные ошибки. Но нам также нужно обрабатывать непредвиденные ошибки. То есть, ошибки могут возникнуть из-за того, что мы что-то упустили при написании кода. Простой подход – это прервать выполнение или хотя бы вернуться на этап, в котором мы имеем полный контроль над происходящим. Недостаточно будет просто подчеркнуть, что совершенно непозволительно игнорировать непредвиденные ошибки. Это недостаток, который может вызвать губительные последствия: например, стать причиной того, что приложение будет предоставлять некорректную информацию пользователю или, что еще хуже, сохранять некорректные данные в базе. Также важно сообщать о возникновении ошибки с той целью, чтобы пользователь не думал о том, что операция прошла успешно, в то время как ваш код на самом деле ничего не выполнил.
Мы часто хотим, чтобы в базе данных изменения были атомарными. Например, задача по переводу денег с одного счета на другой. С этой целью мы должны изменить две записи в таблице CashHoldings и добавить две записи в таблицу Transactions. Абсолютно недопустимо, чтобы ошибки или сбой привели к тому, что деньги будут переведены на счет получателя, а со счета отправителя они не будут списаны. По этой причине обработка ошибок также касается и обработки транзакций. В приведенном примере нам нужно обернуть операцию в BEGIN TRANSACTION и COMMIT TRANSACTION, но не только это: в случае ошибки мы должны убедиться, что транзакция откачена.
2. Основные команды
Мы начнем с обзора наиболее важных команд, которые необходимы для обработки ошибок. Во второй части я опишу все команды, относящиеся к обработке ошибок и транзакций.
2.1 TRY-CATCH
Основным механизмом обработки ошибок является конструкция TRY-CATCH, очень напоминающая подобные конструкции в других языках. Структура такова:
BEGIN TRY
<обычный код>
END TRY
BEGIN CATCH
<обработка ошибок>
END CATCH
Если какая-либо ошибка появится в <обычный код>
, выполнение будет переведено в блок CATCH, и будет выполнен код обработки ошибок.
Как правило, в CATCH откатывают любую открытую транзакцию и повторно вызывают ошибку. Таким образом, вызывающая клиентская программа понимает, что что-то пошло не так. Повторный вызов ошибки мы обсудим позже в этой статье.
Вот очень быстрый пример:
BEGIN TRY
DECLARE @x int
SELECT @x = 1/0
PRINT 'Not reached'
END TRY
BEGIN CATCH
PRINT 'This is the error: ' + error_message()
END CATCH
Результат выполнения: This is the error: Divide by zero error encountered.
Мы вернемся к функции error_message() позднее. Стоит отметить, что использование PRINT в обработчике CATCH приводится только в рамках экспериментов и не следует делать так в коде реального приложения.
Если <обычный код>
вызывает хранимую процедуру или запускает триггеры, то любая ошибка, которая в них возникнет, передаст выполнение в блок CATCH. Если более точно, то, когда возникает ошибка, SQL Server раскручивает стек до тех пор, пока не найдёт обработчик CATCH. И если такого обработчика нет, SQL Server отправляет сообщение об ошибке напрямую клиенту.
Есть одно очень важное ограничение у конструкции TRY-CATCH, которое нужно знать: она не ловит ошибки компиляции, которые возникают в той же области видимости. Рассмотрим пример:
CREATE PROCEDURE inner_sp AS
BEGIN TRY
PRINT 'This prints'
SELECT * FROM NoSuchTable
PRINT 'This does not print'
END TRY
BEGIN CATCH
PRINT 'And nor does this print'
END CATCH
go
EXEC inner_sp
Выходные данные:
This prints
Msg 208, Level 16, State 1, Procedure inner_sp, Line 4
Invalid object name 'NoSuchTable'
Как можно видеть, блок TRY присутствует, но при возникновении ошибки выполнение не передается блоку CATCH, как это ожидалось. Это применимо ко всем ошибкам компиляции, таким как пропуск колонок, некорректные псевдонимы и тому подобное, которые возникают во время выполнения. (Ошибки компиляции могут возникнуть в SQL Server во время выполнения из-за отложенного разрешения имен – особенность, благодаря которой SQL Server позволяет создать процедуру, которая обращается к несуществующим таблицам.)
Эти ошибки не являются полностью неуловимыми; вы не можете поймать их в области, в которой они возникают, но вы можете поймать их во внешней области. Добавим такой код к предыдущему примеру:
CREATE PROCEDURE outer_sp AS
BEGIN TRY
EXEC inner_sp
END TRY
BEGIN CATCH
PRINT 'The error message is: ' + error_message()
END CATCH
go
EXEC outer_sp
Теперь мы получим на выходе это:
This prints
The error message is: Invalid object name 'NoSuchTable'.
На этот раз ошибка была перехвачена, потому что сработал внешний обработчик CATCH.
2.2 SET XACT_ABORT ON
В начало ваших хранимых процедур следует всегда добавлять это выражение:
SET XACT_ABORT, NOCOUNT ON
Оно активирует два параметра сессии, которые выключены по умолчанию в целях совместимости с предыдущими версиями, но опыт доказывает, что лучший подход – это иметь эти параметры всегда включенными. Поведение SQL Server по умолчанию в той ситуации, когда не используется TRY-CATCH, заключается в том, что некоторые ошибки прерывают выполнение и откатывают любые открытые транзакции, в то время как с другими ошибками выполнение последующих инструкций продолжается. Когда вы включаете XACT_ABORT ON, почти все ошибки начинают вызывать одинаковый эффект: любая открытая транзакция откатывается, и выполнение кода прерывается. Есть несколько исключений, среди которых наиболее заметным является выражение RAISERROR.
Параметр XACT_ABORT необходим для более надежной обработки ошибок и транзакций. В частности, при настройках по умолчанию есть несколько ситуаций, когда выполнение может быть прервано без какого-либо отката транзакции, даже если у вас есть TRY-CATCH. Мы видели такой пример в предыдущем разделе, где мы выяснили, что TRY-CATCH не перехватывает ошибки компиляции, возникшие в той же области. Открытая транзакция, которая не была откачена из-за ошибки, может вызвать серьезные проблемы, если приложение работает дальше без завершения транзакции или ее отката.
Для надежной обработки ошибок в SQL Server вам необходимы как TRY-CATCH, так и SET XACT_ABORT ON. Среди них инструкция SET XACT_ABORT ON наиболее важна. Если для кода на промышленной среде только на нее полагаться не стоит, то для быстрых и простых решений она вполне подходит.
Параметр NOCOUNT не имеет к обработке ошибок никакого отношения, но включение его в код является хорошей практикой. NOCOUNT подавляет сообщения вида (1 row(s) affected), которые вы можете видеть в панели Message в SQL Server Management Studio. В то время как эти сообщения могут быть полезны при работе c SSMS, они могут негативно повлиять на производительность в приложении, так как увеличивают сетевой трафик. Сообщение о количестве строк также может привести к ошибке в плохо написанных клиентских приложениях, которые могут подумать, что это данные, которые вернул запрос.
Выше я использовал синтаксис, который немного необычен. Большинство людей написали бы два отдельных выражения:
SET NOCOUNT ON
SET XACT_ABORT ON
Между ними нет никакого отличия. Я предпочитаю версию с SET и запятой, т.к. это снижает уровень шума в коде. Поскольку эти выражения должны появляться во всех ваших хранимых процедурах, они должны занимать как можно меньше места.
3. Основной пример обработки ошибок
После того, как мы посмотрели на TRY-CATCH и SET XACT_ABORT ON, давайте соединим их вместе в примере, который мы можем использовать во всех наших хранимых процедурах. Для начала я покажу пример, в котором ошибка генерируется в простой форме, а в следующем разделе я рассмотрю решения получше.
Для примера я буду использовать эту простую таблицу.
CREATE TABLE sometable(a int NOT NULL,
b int NOT NULL,
CONSTRAINT pk_sometable PRIMARY KEY(a, b))
Вот хранимая процедура, которая демонстрирует, как вы должны работать с ошибками и транзакциями.
CREATE PROCEDURE insert_data @a int, @b int AS
SET XACT_ABORT, NOCOUNT ON
BEGIN TRY
BEGIN TRANSACTION
INSERT sometable(a, b) VALUES (@a, @b)
INSERT sometable(a, b) VALUES (@b, @a)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@trancount > 0 ROLLBACK TRANSACTION
DECLARE @msg nvarchar(2048) = error_message()
RAISERROR (@msg, 16, 1)
RETURN 55555
END CATCH
Первая строка в процедуре включает XACT_ABORT и NOCOUNT в одном выражении, как я показывал выше. Эта строка – единственная перед BEGIN TRY. Все остальное в процедуре должно располагаться после BEGIN TRY: объявление переменных, создание временных таблиц, табличных переменных, всё. Даже если у вас есть другие SET-команды в процедуре (хотя причины для этого встречаются редко), они должны идти после BEGIN TRY.
Причина, по которой я предпочитаю указывать SET XACT_ABORT и NOCOUNT перед BEGIN TRY, заключается в том, что я рассматриваю это как одну строку шума: она всегда должна быть там, но я не хочу, чтобы это мешало взгляду. Конечно же, это дело вкуса, и если вы предпочитаете ставить SET-команды после BEGIN TRY, ничего страшного. Важно то, что вам не следует ставить что-либо другое перед BEGIN TRY.
Часть между BEGIN TRY и END TRY является основной составляющей процедуры. Поскольку я хотел использовать транзакцию, определенную пользователем, я ввел довольно надуманное бизнес-правило, в котором говорится, что если вы вставляете пару, то обратная пара также должна быть вставлена. Два выражения INSERT находятся внутри BEGIN и COMMIT TRANSACTION. Во многих случаях у вас будет много строк кода между BEGIN TRY и BEGIN TRANSACTION. Иногда у вас также будет код между COMMIT TRANSACTION и END TRY, хотя обычно это только финальный SELECT, возвращающий данные или присваивающий значения выходным параметрам. Если ваша процедура не выполняет каких-либо изменений или имеет только одно выражение INSERT/UPDATE/DELETE/MERGE, то обычно вам вообще не нужно явно указывать транзакцию.
В то время как блок TRY будет выглядеть по-разному от процедуры к процедуре, блок CATCH должен быть более или менее результатом копирования и вставки. То есть вы делаете что-то короткое и простое и затем используете повсюду, не особо задумываясь. Обработчик CATCH, приведенный выше, выполняет три действия:
- Откатывает любые открытые транзакции.
- Повторно вызывает ошибку.
- Убеждается, что возвращаемое процедурой значение отлично от нуля.
Эти три действия должны всегда быть там. Мы можете возразить, что строка
IF @@trancount > 0 ROLLBACK TRANSACTION
не нужна, если нет явной транзакции в процедуре, но это абсолютно неверно. Возможно, вы вызываете хранимую процедуру, которая открывает транзакцию, но которая не может ее откатить из-за ограничений TRY-CATCH. Возможно, вы или кто-то другой добавите явную транзакцию через два года. Вспомните ли вы тогда о том, что нужно добавить строку с откатом? Не рассчитывайте на это. Я также слышу читателей, которые возражают, что если тот, кто вызывает процедуру, открыл транзакцию, мы не должны ее откатывать… Нет, мы должны, и если вы хотите знать почему, вам нужно прочитать вторую и третью части. Откат транзакции в обработчике CATCH – это категорический императив, у которого нет исключений.
Код повторной генерации ошибки включает такую строку:
DECLARE @msg nvarchar(2048) = error_message()
Встроенная функция error_message() возвращает текст возникшей ошибки. В следующей строке ошибка повторно вызывается с помощью выражения RAISERROR. Это не самый простой способ вызова ошибки, но он работает. Другие способы мы рассмотрим в следующей главе.
Замечание: синтаксис для присвоения начального значения переменной в DECLARE был внедрен в SQL Server 2008. Если у вас SQL Server 2005, вам нужно разбить строку на DECLARE и выражение SELECT.
Финальное выражение RETURN – это страховка. RAISERROR никогда не прерывает выполнение, поэтому выполнение следующего выражения будет продолжено. Пока все процедуры используют TRY-CATCH, а также весь клиентский код обрабатывает исключения, нет повода для беспокойства. Но ваша процедура может быть вызвана из старого кода, написанного до SQL Server 2005 и до внедрения TRY-CATCH. В те времена лучшее, что мы могли делать, это смотреть на возвращаемые значения. То, что вы возвращаете с помощью RETURN, не имеет особого значения, если это не нулевое значение (ноль обычно обозначает успешное завершение работы).
Последнее выражение в процедуре – это END CATCH. Никогда не следует помещать какой-либо код после END CATCH. Кто-нибудь, читающий процедуру, может не увидеть этот кусок кода.
После прочтения теории давайте попробуем тестовый пример:
EXEC insert_data 9, NULL
Результат выполнения:
Msg 50000, Level 16, State 1, Procedure insert_data, Line 12
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Давайте добавим внешнюю процедуру для того, чтобы увидеть, что происходит при повторном вызове ошибки:
CREATE PROCEDURE outer_sp @a int, @b int AS
SET XACT_ABORT, NOCOUNT ON
BEGIN TRY
EXEC insert_data @a, @b
END TRY
BEGIN CATCH
IF @@trancount > 0 ROLLBACK TRANSACTION
DECLARE @msg nvarchar(2048) = error_message()
RAISERROR (@msg, 16, 1)
RETURN 55555
END CATCH
go
EXEC outer_sp 8, 8
Результат работы:
Msg 50000, Level 16, State 1, Procedure outer_sp, Line 9
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).
Мы получили корректное сообщение об ошибке, но если вы посмотрите на заголовки этого сообщения и на предыдущее поближе, то можете заметить проблему:
Msg 50000, Level 16, State 1, Procedure insert_data, Line 12
Msg 50000, Level 16, State 1, Procedure outer_sp, Line 9
Сообщение об ошибке выводит информацию о расположении конечного выражения RAISERROR. В первом случае некорректен только номер строки. Во втором случае некорректно также имя процедуры. Для простых процедур, таких как наш тестовый пример, это не является большой проблемой. Но если у вас есть несколько уровней вложенных сложных процедур, то наличие сообщения об ошибке с отсутствием указания на место её возникновения сделает поиск и устранение ошибки намного более сложным делом. По этой причине желательно генерировать ошибку таким образом, чтобы можно было определить нахождение ошибочного фрагмента кода быстро, и это то, что мы рассмотрим в следующей главе.
4. Три способа генерации ошибки
4.1 Использование error_handler_sp
Мы рассмотрели функцию error_message(), которая возвращает текст сообщения об ошибке. Сообщение об ошибке состоит из нескольких компонентов, и существует своя функция error_xxx() для каждого из них. Мы можем использовать их для повторной генерации полного сообщения, которое содержит оригинальную информацию, хотя и в другом формате. Если делать это в каждом обработчике CATCH, это будет большой недостаток — дублирование кода. Вам не обязательно находиться в блоке CATCH для вызова error_message() и других подобных функций, и они вернут ту же самую информацию, если будут вызваны из хранимой процедуры, которую выполнит блок CATCH.
Позвольте представить вам error_handler_sp:
CREATE PROCEDURE error_handler_sp AS
DECLARE @errmsg nvarchar(2048),
@severity tinyint,
@state tinyint,
@errno int,
@proc sysname,
@lineno int
SELECT @errmsg = error_message(), @severity = error_severity(),
@state = error_state(), @errno = error_number(),
@proc = error_procedure(), @lineno = error_line()
IF @errmsg NOT LIKE '***%'
BEGIN
SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') +
', Line ' + ltrim(str(@lineno)) + '. Errno ' +
ltrim(str(@errno)) + ': ' + @errmsg
END
RAISERROR('%s', @severity, @state, @errmsg)
Первое из того, что делает error_handler_sp – это сохраняет значение всех error_xxx() функций в локальные переменные. Я вернусь к выражению IF через секунду. Вместо него давайте посмотрим на выражение SELECT внутри IF:
SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') +
', Line ' + ltrim(str(@lineno)) + '. Errno ' +
ltrim(str(@errno)) + ': ' + @errmsg
Цель этого SELECT заключается в форматировании сообщения об ошибке, которое передается в RAISERROR. Оно включает в себя всю информацию из оригинального сообщения об ошибке, которое мы не можем вставить напрямую в RAISERROR. Мы должны обработать имя процедуры, которое может быть NULL для ошибок в обычных скриптах или в динамическом SQL. Поэтому используется функция COALESCE. (Если вы не понимаете форму выражения RAISERROR, я рассказываю о нем более детально во второй части.)
Отформатированное сообщение об ошибке начинается с трех звездочек. Этим достигаются две цели: 1) Мы можем сразу видеть, что это сообщение вызвано из обработчика CATCH. 2) Это дает возможность для error_handler_sp отфильтровать ошибки, которые уже были сгенерированы один или более раз, с помощью условия NOT LIKE ‘***%’ для того, чтобы избежать изменения сообщения во второй раз.
Вот как обработчик CATCH должен выглядеть, когда вы используете error_handler_sp:
BEGIN CATCH
IF @@trancount > 0 ROLLBACK TRANSACTION
EXEC error_handler_sp
RETURN 55555
END CATCH
Давайте попробуем несколько тестовых сценариев.
EXEC insert_data 8, NULL
EXEC outer_sp 8, 8
Результат выполнения:
Msg 50000, Level 16, State 2, Procedure error_handler_sp, Line 20
*** [insert_data], Line 5. Errno 515: Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 50000, Level 14, State 1, Procedure error_handler_sp, Line 20
*** [insert_data], Line 6. Errno 2627: Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).
Заголовки сообщений говорят о том, что ошибка возникла в процедуре error_handler_sp, но текст сообщений об ошибках дает нам настоящее местонахождение ошибки – как название процедуры, так и номер строки.
Я покажу еще два метода вызова ошибок. Однако error_handler_sp является моей главной рекомендацией для читателей, которые читают эту часть. Это — простой вариант, который работает на всех версиях SQL Server начиная с 2005. Существует только один недостаток: в некоторых случаях SQL Server генерирует два сообщения об ошибках, но функции error_xxx() возвращают только одну из них, и поэтому одно из сообщений теряется. Это может быть неудобно при работе с административными командами наподобие BACKUPRESTORE, но проблема редко возникает в коде, предназначенном чисто для приложений.
4.2. Использование ;THROW
В SQL Server 2012 Microsoft представил выражение ;THROW для более легкой обработки ошибок. К сожалению, Microsoft сделал серьезную ошибку при проектировании этой команды и создал опасную ловушку.
С выражением ;THROW вам не нужно никаких хранимых процедур. Ваш обработчик CATCH становится таким же простым, как этот:
BEGIN CATCH
IF @@trancount > 0 ROLLBACK TRANSACTION
;THROW
RETURN 55555
END CATCH
Достоинство ;THROW в том, что сообщение об ошибке генерируется точно таким же, как и оригинальное сообщение. Если изначально было два сообщения об ошибках, оба сообщения воспроизводятся, что делает это выражение еще привлекательнее. Как и со всеми другими сообщениями об ошибках, ошибки, сгенерированные ;THROW, могут быть перехвачены внешним обработчиком CATCH и воспроизведены. Если обработчика CATCH нет, выполнение прерывается, поэтому оператор RETURN в данном случае оказывается не нужным. (Я все еще рекомендую оставлять его, на случай, если вы измените свое отношение к ;THROW позже).
Если у вас SQL Server 2012 или более поздняя версия, измените определение insert_data и outer_sp и попробуйте выполнить тесты еще раз. Результат в этот раз будет такой:
Msg 515, Level 16, State 2, Procedure insert_data, Line 5
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 2627, Level 14, State 1, Procedure insert_data, Line 6
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).
Имя процедуры и номер строки верны и нет никакого другого имени процедуры, которое может нас запутать. Также сохранены оригинальные номера ошибок.
В этом месте вы можете сказать себе: действительно ли Microsoft назвал команду ;THROW? Разве это не просто THROW? На самом деле, если вы посмотрите в Books Online, там не будет точки с запятой. Но точка с запятой должны быть. Официально они отделяют предыдущее выражение, но это опционально, и далеко не все используют точку с запятой в выражениях T-SQL. Более важно, что если вы пропустите точку с запятой перед THROW, то не будет никакой синтаксической ошибки. Но это повлияет на поведение при выполнении выражения, и это поведение будет непостижимым для непосвященных. При наличии активной транзакции вы получите сообщение об ошибке, которое будет полностью отличаться от оригинального. И еще хуже, что при отсутствии активной транзакции ошибка будет тихо выведена без обработки. Такая вещь, как пропуск точки с запятой, не должно иметь таких абсурдных последствий. Для уменьшения риска такого поведения, всегда думайте о команде как о ;THROW (с точкой с запятой).
Нельзя отрицать того, что ;THROW имеет свои преимущества, но точка с запятой не единственная ловушка этой команды. Если вы хотите использовать ее, я призываю вас прочитать по крайней мере вторую часть этой серии, где я раскрываю больше деталей о команде ;THROW. До этого момента, используйте error_handler_sp.
4.3. Использование SqlEventLog
Третий способ обработки ошибок – это использование SqlEventLog, который я описываю очень детально в третьей части. Здесь я лишь сделаю короткий обзор.
SqlEventLog предоставляет хранимую процедуру slog.catchhandler_sp, которая работает так же, как и error_handler_sp: она использует функции error_xxx() для сбора информации и выводит сообщение об ошибке, сохраняя всю информацию о ней. Вдобавок к этому, она логирует ошибку в таблицу splog.sqleventlog. В зависимости от типа приложения, которое у вас есть, эта таблица может быть очень ценным объектом.
Для использования SqlEventLog, ваш обработчик CATCH должен быть таким:
BEGIN CATCH
IF @@trancount > 0 ROLLBACK TRANSACTION
EXEC slog.catchhandler_sp @@procid
RETURN 55555
END CATCH
@@procid возвращает идентификатор объекта текущей хранимой процедуры. Это то, что SqlEventLog использует для логирования информации в таблицу. Используя те же тестовые сценарии, получим результат их работы с использованием catchhandler_sp:
Msg 50000, Level 16, State 2, Procedure catchhandler_sp, Line 125
{515} Procedure insert_data, Line 5
Cannot insert the value NULL into column 'b', table 'tempdb.dbo.sometable'; column does not allow nulls. INSERT fails.
Msg 50000, Level 14, State 1, Procedure catchhandler_sp, Line 125
{2627} Procedure insert_data, Line 6
Violation of PRIMARY KEY constraint 'pk_sometable'. Cannot insert duplicate key in object 'dbo.sometable'. The duplicate key value is (8, 8).
Как вы видите, сообщение об ошибке отформатировано немного не так, как это делает error_handler_sp, но основная идея такая же. Вот образец того, что было записано в таблицу slog.sqleventlog:
logid | logdate | errno | severity | logproc | linenum | msgtext |
1 | 2015-01-25 22:40:24.393 | 515 | 16 | insert_data | 5 | Cannot insert … |
2 | 2015-01-25 22:40:24.395 | 2627 | 14 | insert_data | 6 | Violation of … |
Если вы хотите попробовать SqlEventLog, вы можете загрузить файл sqleventlog.zip. Инструкция по установке находится в третьей части, раздел Установка SqlEventLog.
5. Финальные замечания
Вы изучили основной образец для обработки ошибок и транзакций в хранимых процедурах. Он не идеален, но он должен работать в 90-95% вашего кода. Есть несколько ограничений, на которые стоит обратить внимание:
- Как мы видели, ошибки компиляции не могут быть перехвачены в той же процедуре, в которой они возникли, а только во внешней процедуре.
- Пример не работает с пользовательскими функциями, так как ни TRY-CATCH, ни RAISERROR нельзя в них использовать.
- Когда хранимая процедура на Linked Server вызывает ошибку, эта ошибка может миновать обработчик в хранимой процедуре на локальном сервере и отправиться напрямую клиенту.
- Когда процедура вызвана как INSERT-EXEC, вы получите неприятную ошибку, потому что ROLLBACK TRANSACTION не допускается в данном случае.
- Как упомянуто выше, если вы используете error_handler_sp или SqlEventLog, мы потеряете одно сообщение, когда SQL Server выдаст два сообщения для одной ошибки. При использовании ;THROW такой проблемы нет.
Я рассказываю об этих ситуациях более подробно в других статьях этой серии.
Перед тем как закончить, я хочу кратко коснуться триггеров и клиентского кода.
Триггеры
Пример для обработки ошибок в триггерах не сильно отличается от того, что используется в хранимых процедурах, за исключением одной маленькой детали: вы не должны использовать выражение RETURN (потому что RETURN не допускается использовать в триггерах).
С триггерами важно понимать, что они являются частью команды, которая запустила триггер, и в триггере вы находитесь внутри транзакции, даже если не используете BEGIN TRANSACTION.
Иногда я вижу на форумах людей, которые спрашивают, могут ли они написать триггер, который не откатывает в случае падения запустившую его команду. Ответ таков: нет способа сделать это надежно, поэтому не стоит даже пытаться. Если в этом есть необходимость, по возможности не следует использовать триггер вообще, а найти другое решение. Во второй и третьей частях я рассматриваю обработку ошибок в триггерах более подробно.
Клиентский код
У вас должна быть обработка ошибок в коде клиента, если он имеет доступ к базе. То есть вы должны всегда предполагать, что при любом вызове что-то может пойти не так. Как именно внедрить обработку ошибок, зависит от конкретной среды.
Здесь я только обращу внимание на важную вещь: реакцией на ошибку, возвращенную SQL Server, должно быть завершение запроса во избежание открытых бесхозных транзакций:
IF @@trancount > 0 ROLLBACK TRANSACTION
Это также применимо к знаменитому сообщению Timeout expired (которое является не сообщением от SQL Server, а от API).
6. Конец первой части
Это конец первой из трех частей серии. Если вы хотели изучить вопрос обработки ошибок быстро, вы можете закончить чтение здесь. Если вы настроены идти дальше, вам следует прочитать вторую часть, где наше путешествие по запутанным джунглям обработки ошибок и транзакций в SQL Server начинается по-настоящему.
… и не забывайте добавлять эту строку в начало ваших хранимых процедур:
SET XACT_ABORT, NOCOUNT ON
Someone sent me a request to diagnose the error message : Error: 17300, Severity: 16, State: 1. (Params:). The error is printed in terse mode because there was error during formatting. Tracing, ETW, notifications etc are skipped.
A close inspection of the error logs revealed some relate messages. Most importantly
There was insufficient memory to run this query
Observations:
Max Memory not set. It was set with no limit . This means it was competing with OS memory requirements
One of the nice features of SQL Server when there is extreme memory pressure is a good level of detail in the error log. The output of errorlog had dbcc memorystatus dump and what I noticed was At the time of the problem .7 GB was left – very LOW and no memory left in buffer pool
Message
Process/System Counts Value
—————————————- ———-
Available Physical Memory 771760128
Available Virtual Memory 140699792551936
Available Paging File 2168729600
Working Set 10083323904
Percent of Committed Memory in WS 78
Page Faults 3068606988
System physical memory high 0
System physical memory low 0
Process physical memory low 1
Process virtual memory low 0
A quick review of the DBCC MEMORYSTATUS revealed the CACHESTORE_SQLCP memory clerk as one of the largest consumers. The OBJECTSTORE_SQLCP is Object Plans include plans for stored procedures, functions, and triggers
CACHESTORE_SQLCP (node 0) KB
—————————————- ———-
VM Reserved 0
VM Committed 0
Locked Pages Allocated 0
SM Reserved 0
SM Committed 0
Pages Allocated 11468784
Advice
— Specify Optimize for AdHoc = true
— Always configure MAX SERVER MEMORY Setting . Read up on other settings during installation on SQL Server Install Checklist
— Monitor the size and usage of your plan cache .This is how : SQL Memory usage query and cachestore_sqlcp (SQL Server DBA)
Author: Tom Collins (http://www.sqlserver-dba.com)
Share:
MySQL — система управления базами данных (СУБД) с открытым исходным кодом от компании Oracle. Она была разработана и оптимизирована специально для работы веб-приложений. MySQL является неотъемлемой частью таких веб-сервисов, как Facebook, Twitter, Wikipedia, YouTube и многих других.
Эта статья расскажет, как определять, с чем связаны частые ошибки на сервере MySQL, и устранять их.
Не удаётся подключиться к локальному серверу
Одной из распространённых ошибок подключения клиента к серверу является «ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)».
Эта ошибка означает, что на хосте не запущен сервер MySQL (mysqld
) или вы указали неправильное имя файла сокета Unix или порт TCP/IP при попытке подключения.
Убедитесь, что сервер работает. Проверьте процесс с именем mysqld
на хосте сервера, используя команды ps или grep, как показано ниже.
$ ps xa | grep mysqld | grep -v mysqld
Если эти команды не показывают выходных данных, то сервер БД не работает. Поэтому клиент не может подключиться к нему. Чтобы запустить сервер, выполните команду systemctl.
$ sudo systemctl start mysql #Debian/Ubuntu
$ sudo systemctl start mysqld #RHEL/CentOS/Fedora
Чтобы проверить состояние службы MySQL, используйте следующую команду:
$ sudo systemctl status mysql #Debian/Ubuntu
$ sudo systemctl status mysqld #RHEL/CentOS/Fedora
Если в результате выполнения команды произошла ошибка службы MySQL, вы можете попробовать перезапустить службу и ещё раз проверить её состояние.
$ sudo systemctl restart mysql
$ sudo systemctl status mysql
Если сервер работает (как показано) и вы по-прежнему видите эту ошибку, вам следует проверить, не заблокирован ли порт TCP/IP брандмауэром или любой другой службой блокировки портов.
Для поиска порта, который прослушивается сервером, используйте команду netstat
.
$ sudo netstat -tlpn | grep "mysql"
Ещё одна похожая и часто встречающаяся ошибка подключения — «(2003) Can’t connect to MySQL server on ‘server’ (10061)». Это означает, что в сетевом соединении было отказано.
Следует проверить, работает ли в системе сервер MySQL (смотрите выше) и на тот ли порт вы подключаетесь (как найти порт, можно посмотреть выше).
Похожие частые ошибки, с которыми вы можете столкнуться при попытке подключиться к серверу MySQL:
ERROR 2003: Cannot connect to MySQL server on 'host_name' (111)
ERROR 2002: Cannot connect to local MySQL server through socket '/tmp/mysql.sock' (111)
Ошибки запрета доступа в MySQL
В MySQL учётная запись (УЗ) определяется именем пользователя и клиентским хостом, с которого пользователь может подключиться. УЗ может также иметь данные для аутентификации (например, пароль).
Причин для запрета доступа может быть много. Одна из них связана с учётными записями MySQL, которые сервер разрешает использовать клиентским программам при подключении. Это означает, что имя пользователя, указанное в соединении, может не иметь прав доступа к базе данных.
В MySQL есть возможность создавать учётные записи, позволяющие пользователям клиентских программ подключаться к серверу и получать доступ к данным. Поэтому при ошибке доступа проверьте разрешение УЗ на подключение к серверу через клиентскую программу.
Увидеть разрешённые привилегии учётной записи можно, выполнив в консоли команду SHOW GRANTS
Входим в консоль (пример для Unix, для Windows консоль можно найти в стартовом меню):
В консоли вводим команду:
> SHOW GRANTS FOR 'tecmint'@'localhost';
Дать привилегии конкретному пользователю в БД по IP-адресу можно, используя следующие команды:
> grant all privileges on *.test_db to 'tecmint'@'192.168.0.100';
> flush privileges;
Ошибки запрещённого доступа могут также возникнуть из-за проблем с подключением к MySQL (см. выше).
Потеря соединения с сервером MySQL
С этой ошибкой можно столкнуться по одной из следующих причин:
- плохое сетевое соединение;
- истекло время ожидания соединения;
- размер BLOB больше, чем
max_allowed_packet
.
В первом случае убедитесь, что у вас стабильное сетевое подключение (особенно, если подключаетесь удалённо).
Если проблема с тайм-аутом соединения (особенно при первоначальном соединении MySQL с сервером), увеличьте значение параметра connect_timeout
.
В случае с размером BLOB нужно установить более высокое значение для max_allowed_packet
в файле конфигурации /etc/my.cnf
в разделах [mysqld]
или [client]
как показано ниже.
[mysqld]
connect_timeout=100
max_allowed_packet=500M
Если файл конфигурации недоступен, это значение можно установить с помощью следующей команды.
> SET GLOBAL connect_timeout=100;
> SET GLOBAL max_allowed_packet=524288000;
Слишком много подключений
Эта ошибка означает, что все доступные соединения используются клиентскими программами. Количество соединений (по умолчанию 151) контролируется системной переменной max_connections
. Устранить проблему можно, увеличив значение переменной в файле конфигурации /etc/my.cnf
.
[mysqld]
max_connections=1000
Недостаточно памяти
Если такая ошибка возникла, это может означать, что в MySQL недостаточно памяти для хранения всего результата запроса.
Сначала нужно убедиться, что запрос правильный. Если это так, то нужно выполнить одно из следующих действий:
- если клиент MySQL используется напрямую, запустите его с ключом
--quick switch
, чтобы отключить кешированные результаты; - если вы используете драйвер MyODBC, пользовательский интерфейс (UI) имеет расширенную вкладку с опциями. Отметьте галочкой «Do not cache result» (не кешировать результат).
Также может помочь MySQL Tuner. Это полезный скрипт, который подключается к работающему серверу MySQL и даёт рекомендации по настройке для более высокой производительности.
$ sudo apt-get install mysqltuner #Debian/Ubuntu
$ sudo yum install mysqltuner #RHEL/CentOS/Fedora
$ mysqltuner
MySQL продолжает «падать»
Если такая проблема возникает, необходимо выяснить, заключается она в сервере или в клиенте. Обратите внимание, что многие сбои сервера вызваны повреждёнными файлами данных или индексными файлами.
Вы можете проверить состояние сервера, чтобы определить, как долго он работал.
$ sudo systemctl status mysql #Debian/Ubuntu
$ sudo systemctl status mysqld #RHEL/CentOS/Fedora
Чтобы узнать время безотказной работы сервера, запустите команду mysqladmin
.
$ sudo mysqladmin version -p
Кроме того, можно остановить сервер, сделать отладку MySQL и снова запустить службу. Для отображения статистики процессов MySQL во время выполнения других процессов откройте окно командной строки и введите следующее:
$ sudo mysqladmin -i 5 status
Или
$ sudo mysqladmin -i 5 -r status
Заключение
Самое важное при диагностике — понять, что именно вызвало ошибку. Следующие шаги помогут вам в этом:
- Первый и самый важный шаг — просмотреть журналы MySQL, которые хранятся в каталоге
/var/log/mysql/
. Вы можете использовать утилиты командной строки вродеtail
для чтения файлов журнала. - Если служба MySQL не запускается, проверьте её состояние с помощью
systemctl
. Или используйте командуjournalctl
(с флагом-xe
) в systemd. - Вы также можете проверить файл системного журнала (например,
/var/log/messages
) на предмет обнаружения ошибок. - Попробуйте использовать такие инструменты, как Mytop, glances, top, ps или htop, чтобы проверить, какая программа использует весь ресурс процессора или блокирует машину. Они также помогут определить нехватку памяти, дискового пространства, файловых дескрипторов или какого-либо другого важного ресурса.
- Если проблема в каком-либо процессе, можно попытаться его принудительно остановить, а затем запустить (при необходимости).
- Если вы уверены, что проблемы именно на стороне сервера, можете выполнить команды:
mysqladmin -u root ping
илиmysqladmin -u root processlist
, чтобы получить от него ответ. - Если при подключении проблема не связана с сервером, проверьте, нормально ли работает клиент. Попробуйте получить какие-либо его выходные данные для устранения неполадок.
Перевод статьи «Useful Tips to Troubleshoot Common Errors in MySQL»