I have a database running in MariaDB. I use auto numbering for the primary key's, on my local development system everything works as expected.
The same database and system is installed on a clients system, in this case the client has chosen to run the installation on a virtual machine running Windows Server.
This system has been working find for several weeks, over the last few days some strange problems have occurred, today I tried to edit an existing record and instead of the record being updated a new record with a primary key of 0 was added to the database, so the auto increment isn't working reliably.
How can this happen? What can cause it?
I will check and repair the database.
Auto increment only kicks in when you insert and no value (for that attribute) is supplied. So you can still manually update it. I would say auto increment has not failed.
Fixed, the same database on two different systems, same version of mariadb, but a slightly different version of Windows. A stored procedure on one system was send 0 instead of null. On one system the 0 was treated as null and a new record was created, on the other system the 0 was interpreted as a database id and this caused the problem.
I now ensure that null is send if the ID is not > 0.
Related
This question was migrated from Stack Overflow because it can be answered on Database Administrators Stack Exchange.
Migrated 5 days ago.
I've been tasked with migrating data from an instance of SQL Server 2000 to 2019. There are a total of four databases to bring over, three of which I was able to backup/restore into 2008 and then into 2019 without any issues. Please note: I am not a DBA in any sense, though I'm the closest thing to one on hand.
The fourth and final database presented the following error that prevented moving from 2008 to 2019:
System.Data.SqlClient.SqlError: An error occurred while processing the log for database 'DbNameHere'. The log block version 2 is unsupported. This server supports log version 3 to 6. (Microsoft.SqlServer.SmoExtended)
Is there a simple fix for this problem that I'm missing in the various SSMS menus?
Alternatively, is there a way to copy raw data from one server to another via, for instance, a flat file, and preserve the identity columns as identity columns? That is, I don't want to just strip that column and bulk insert, as they are often used as foreign keys in other tables, and with twenty-some-odd years of data, something is bound to break in doing this.
An example of an ideal final result in this solution would be something like: legacy table X has 1000 rows, the last of which has an identity column value of 1000. Once the move is complete, new table X has 1000 rows, the last of which has an identity column value of 1000, and upon insert the next row automatically increments to 1001.
Apart from unsuccessfully messing around with flat files, I've also tried the "Copy Database" option in SSMS, which also failed.
I would attempt to get SQL Server to rebuild the transaction log. Based on the error message, that might sort out the situation.
You first use sp_detach_db to detach the database. It is now very likely that the ldf file isn't needed when you do a subsequent attach, and perhaps rebuilding the log this way will sort the situation.
Then you attach the database, without the ldf file. Use CREATE DATABASE with either of the FOR ATTACH or FOR ATTACH_REBUILD_LOG options.
I would do this on the 2008 instance, since from what I understand you got the database in there successfully. But feel free to play around regarding on which version (2000 or 2008) you do the detach and also on which version (2000, 2008, 2019) you do the attach.
Interesting problem: I have a SQL Server CE 3.5 database with some data in it. I run a query on the database, using a mobile device and obtain a result set.
This works fine 99% of the time, but on occasion I get records in the database where the query returns an empty result set.
If I take a copy of the same database file from my mobile device and connect to it with Query analyzer, then run the exact same query (as copied/pasted from the debugger), the query returns records. The query itself does a JOIN and GROUP BY on two tables by a referential identity key field.
Now if I make a clone the same records involved via a series of:
INSERT INTO MyTable (EntireFieldListExceptForIDKey)
SELECT
(EntireFieldListExceptForIDKey)
FROM
MyTable
WHERE
IDKey = Original
The query is now able to correctly assemble a result set on the cloned records on the mobile device.
Can anyone explain this, and possibly how to detect/overcome?
This is most likely due to a corrupt index, as both copying the file to your desktop and creating a new table will cause an Index rebuild.
It is recommended to regularly Compact your database to prevent this - also make sure you are using the latest runtime binaries.
This question already has answers here:
Identity increment is jumping in SQL Server database
(6 answers)
Closed 7 years ago.
I am using Sql server 2012(Denali). I wonder why all identity column values start from 1001 and so on. At the beginning Identity column starts from 1,2 and so on and adding identity smoothly, but suddenly it jumps to 1001,1002 and onwards for all the table in the database containing identity column. What could be the reason? Please assist.
Microsoft has changed the way they deal with identity values in SQL Server 2012 and as a result of this you can see identity gaps between your records after rebooting your SQL server instance or your server machine. There might be some other reasons for this id gaps, it may be due to automatic server restart after installing an update.
You can use below two choices
Use trace flag 272
o This will cause a log record to be generated for each generated identity value. The performance of identity generation may be impacted by turning on this trace flag.
Use a sequence generator with the NO CACHE setting
Setting Trace Flag 272 on SQL Server 2012 that you are expecting here
Open "SQL Server Configuration Manager"
Click "SQL Server Services" on the left pane
Right-click on your SQL Server instance name on the right pane ->Default: SQL Server(MSSQLSERVER)
Click "Properties"
Click "Startup Parameters"
On the "specify a startup parameter" textbox type "-T272"
Click "Add"
Confirm the changes
I believe you have the explanation in a comment to this connect item. Failover or Restart Results in Reseed of Identity
To boost the preformance for high end machines, we introduce
preallocation for identity value in 2012. And this feature can be
disabled by using TF 272 (then you will get the behaviour from
2008R2).
The identity properties are stored separately in metadata. If a value
is used in identity and increment is called, then the new seed value
will be set. No operation, including Rollback, Failover, ..... can
change the seed value except DBCC reseed. Failover applies for the
table object, but no the identity object. So for failover, you can
call checkpoint before manual failover, but you may see gap for
unplanned cases. If gap is a concern, then I suggest you to use TF
272.
For control manager shutdown, we have a fix for next verion (with
another TF). This fix will take care of most control manager shutdown
cases.
I guess you could use sequence instead, sequence gives you 100% complete control, and is in many ways far superior in comparison to identity...
Identity is just so damn easy and convenient
http://msdn.microsoft.com/en-us/library/ff878091.aspx
As far as i know, when you do a insert with identity and fails, the identity is used anyway, Verified
with sequence you can make it "fill" gaps using cycle.
Although, as Amy Barrett is pointing out this is created out of scope of the transaction.
There is a performance optimization when you are using cache that might be useful as well.
I've been trying to figure out how to properly accommodate how to handle 'Identity' columns when generating a script to re-create the database.
The original reason why I need to generate a script for this is because I have to 'downgrade' a SQL database to an older version. I know everything in the database (v10.5) is compatible with the older version (v10.0). The issue I'm facing is that out of 3 different methods of copying the database, it always fails with the fact that it cannot maintain the original ID fields (which are identity).
Every table of mine has the very first column ID: Int = PK & Identity. I also have many cases where a table doesn't perfectly go sequential in this column, for example, 1, 2, 3, 5, 8, 12, 13, etc. That is simply because those records had been deleted in the past. But it seems as if it's impossible to re-insert the original ID numbers in the same order as they used to be...
So how do I copy (without backup/restore) a database in its entirety from Server A to Server B? NOTE: I can connect to both databases on both servers from the Management Studio. Also, the destination server is not mine, it is a shared hosted DB and I have access only to my database. I have no authority to change destination server settings.
I've tried the following:
Generate script for entire database option
Export database option
Backup/Restore database - fails because of version mis-match
I'm guessing that I may just have to temporarily 'disable' the identity specification on all the tables, insert the data, then switch identity back on again. But I am horrible with writing scripts for manipulating the database structure. Data its self, I can do. But manipulating the database structure, I've gotten so used to using tools for this that I've never even taken the time to work with the scripts - and other than this particular scenario, hope that I never have to learn either.
I actually figured it out. I already knew that there must be a way to temporarily disable the identity specification, but the solution was a little different. Instead of 'disabling' and 're-enabling' the identity specification, there's another command (as in a comment above) called IDENTITY_INSERT which when switched on, it allows inserting values to an identity field - and you need to ensure it gets switched back off too. The IDENTITY_INSERT switch is per-connection-session, so it does not affect other sessions. As long as IDENTITY_INSERT is on, you can insert records with a specific value for that identity field - so long as it's still within the primary key constraints.
The actual solution was NOT to write a script with SET IDENTITY_INSERT MyTableName ON, but rather in the database export utility (in SQL management studio), when selecting the tables, select all the tables and choose the advanced setting to use IDENTITY_INSERT.
I have a utility which:
grabs sql commands from a flat text file
executes them sequentially against SQL Server located on the same machine
and reports an error if an UPDATE command affects ZERO ROWS (there should never be an update command in this file that doesn't affect a record, hence it being recorded as an error)
The utility also logs any failed commands.
Yet the final data in the database seems to be wrong/stale, even though my utility is reporting no failed updates and no failed commands.
I know the first and most obvious culprit is some kind of logic or runtime error in my programming of the utility itself, but I just need to know of it's THEORETICALLY possible for SQL Server to report that at least one row was affected and yet no apply the change.
If it helps, the utility always seems to correctly execute the same number of commands and the final stale/wrong data is always the same i.e. it seems to correctly execute a certain number of commands that are being successfully queried against the database, then failing.
Thanks.
EDIT:
I should also note that this utility is exhibiting this behavior across 4 different production servers each with their own dedicated local database server, and that these are beefy machines with 8-16 GB RAM each that are managed by a professional sysadmin.
Based on what you say...
It is possible for the "xx rows affected" to be misleading if you have a trigger firing. You may be reading the count from the trigger. If so, add SET NOCOUNT ON to the trigger
Alternatively, the data is the same, so you actually do dummy update with the same values. Add a WHERE clause to test for differences for example.
BEGIN TRANSACTION
UPDATE MyTable
SET Message = ''
WHERE ID = 2
ROLLBACK TRANSACTION
Messages:
(1 row(s) affected)