When I attempt to create a database diagram, I get the following error:
Cannot insert the value NULL into column 'diagram_id', table 'MyDB.dbo.sysdiagrams'; column does
not allow nulls. INSERT fails.
The statement has been terminated.
The 'sp_creatediagram' procedure attempted to return a status of NULL, which is not allowed. A status of
0 will be returned instead. (.Net SqlClient Data Provider)
I am using SSMS 2012.
The database is set at a compatibility level of SQL Server 2012 (110)
##Version is Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
Your problem is the diagram_ID when the table was created probably looked something like this
CREATE TABLE <table_name>
( diagram_ID INT NOT NULL PRIMARY KEY,
n...,
)
This basically means that a NULL value cannot be inserted into that column because of the NOT NULL condition. So an insert statement like:
INSERT INTO <table_name>
(Diagram_ID, n...,)
VALUES
(NULL, n...,)
Would fail because of the NULL you would need to have a value in there like (since I called it an integer):
INSERT INTO <table_name>
(Diagram_ID, n...,)
VALUES
(23, n...,)
The column may also be an indentity column in which case you have no controll over what can be inserted into the table.
Go to system tables and look for systemdiagrams table, and turn to YES the "indentity Specification" property for the field diagram_id
Hope this will help you, this script solved my issues
DROP TABLE dbo.sysdiagrams;
GO
CREATE TABLE [dbo].[sysdiagrams]
(
[name] [sysname] NOT NULL,
[principal_id] [int] NOT NULL,
[diagram_id] [int] IDENTITY(1,1) PRIMARY KEY,
[version] [int] NULL,
[definition] [varbinary](max) NULL,
CONSTRAINT [UK_principal_name] UNIQUE ([principal_id],[name])
);
GO
EXEC sys.sp_addextendedproperty
#name=N'microsoft_database_tools_support',
#value=1 ,
#level0type=N'SCHEMA',
#level0name=N'dbo',
#level1type=N'TABLE',
#level1name=N'sysdiagrams';
GO
Related
I have a table Values with 3 columns:
CREATE TABLE [dbo].[Values]
(
[Id] [uniqueidentifier] NOT NULL,
[Value] [nvarchar](150) NOT NULL,
[CreatedOnUtc] [datatime2](7) NOT NULL
)
I want SQL Server to set the value of CreatedOnUtc to UTC-Now whenever a new entry is created, and not allow an external command to set this value.
Is this possible?
This is sort of two questions. For the first:
CREATE TABLE [dbo].[Values] (
[Id] [uniqueidentifier] NOT NULL,
[Value] [nvarchar](150) NOT NULL,
[CreatedOnUtc] [datetime2](7) NOT NULL DEFAULT SYSUTCDATETIME()
);
The canonical way to prevent changes to the column is to use a trigger that prevents the value from being updated or inserted.
Note that Values is a really bad name for a table because it is a SQL keyword and SQL Server reserved word. Choose identifiers that do not need to be escaped.
There are other ways. For instance, you could turn off DML access to the table. Then create a view without CreatedOnUtc and only allow inserts and updates through the view.
I need to create an Index on two columns (within a table variable) which do not form unique key.
Table structure is shown below -
DECLARE #Sample TABLE (
[AssetSk] [int] NOT NULL,
[DateSk] [int] NOT NULL,
[Count] [numeric](38, 2) NULL
)
I am trying to add Index as shown below -
INDEX AD1 CLUSTERED([AssetSk],[DateSk])
However it gives me the following error while running it on SQL Server 2012
" Incorrect syntax near 'INDEX'. If this is intended as a part of a table hint, A WITH keyword and parenthesis are now required. See SQL Server Books Online for proper syntax."
However, this runs perfectly on SQL Server 2014 . Is there any way that I could run it on SQL Server 2012 .
You can't build index other than unique key at table variable using SQL Server version prior to 2014.
However, you can do the trick: add one more colummn with autoincremented value and create unique index including columns you need and this new one.
DECLARE #Sample TABLE (
[ID] bigint identity(1, 1),
[AssetSk] [int] NOT NULL,
[DateSk] [int] NOT NULL,
[Count] [numeric](38, 2) NULL,
UNIQUE NONCLUSTERED ([AssetSk],[DateSk], ID)
)
Update: In fact, creation of such an index on table variable can be useless. Normally SQL Server estimates that a table variable has a single row, thus it will not use this index with relatively high probability.
As far as I know in SQL Server 2012 and below you can not add indexes to table variables. To add an index you must declare the table like this:
CREATE TABLE #Sample (
[AssetSk] [int] NOT NULL,
[DateSk] [int] NOT NULL,
[Count] [numeric](38, 2) NULL
)
And after you can create the index you need like this
CREATE CLUSTERED INDEX IX_MyIndex
ON #Sample ([AssetSk],[DateSk])
Of course, after you're done with the table in four function you can call
DROP TABLE #Sample
I have a table
CREATE TABLE [misc]
(
[misc_id] [int] NOT NULL,
[misc_group] [nvarchar](255) NOT NULL,
[misc_desc] [nvarchar](255) NOT NULL
)
where misc_id [int] not null should have been IDENTITY (1,1) but is not and now I'm having issues
With a simple form that insert into this table but since misc_id is looking for a number that a user would not know unless they have access to the database.
I know a option would be to create another column make it IDENTITY(1,1) and copy that data.
Is there another way I will be able to get around this?
INSERT INTO misc (misc_group, misc_desc)
VALUES ('#misc_group#', '#misc_desc#')
I have SQL Server 2012
You should re-create your table with the desired identity column. The following statements will get you close. SQL Server will automatically adjust the table's identity field to MAX(misc_id) + 1 as you're migrating data.
You'll obviously need to stop trying to insert misc_id with new records. You'll want to retrieve the SCOPE_IDENTITY() column after inserting records.
-- Note: I'd recommend having SSMS generate your base create statement so you know you didn't miss anything. You'll have to export the indexes and foreign keys as well. Add them after populating data to improve performance and reduce fragmentation.
CREATE TABLE [misc_new]
(
[misc_id] [int] NOT NULL IDENTITY(1,1),
[misc_group] [nvarchar](255) NOT NULL,
[misc_desc] [nvarchar](255) NOT NULL
-- Todo: Don't forget primary key but can be added later (not recommended).
)
GO
SET IDENTITY_INSERT misc_new ON;
INSERT INTO misc_new
(
[misc_id],
[misc_group],
[misc_desc]
)
SELECT
[misc_id],
[misc_group],
[misc_desc]
FROM misc
ORDER BY misc_id;
SET IDENTITY_INSERT misc_new OFF;
GO
EXEC sp_rename 'misc', 'misc_old';
EXEC sp_rename 'misc_new', 'misc';
GO
If altering the table is not an option, you can try having a different table with the latest [misc_id] value inserted, so whenever you insert a new record into the table, you retrieve this value, add 1, and use it as your new Id. Just don't forget to update the table after.
Changing a int column to an identity can cause problems because by default you cannot insert a value into an identity column without use the set identity_insert command on. So if you have existing code that inserts a value into the identity column it will fail. However its much easier to allow SQL Server to insert values(that is change it to an identity column) so I would change misc_id into an identity column and make sure that there are no programs inserting values into misc_id.
In MSSQL 2012 you can use SEQUENCE objects:
CREATE SEQUENCE [dbo].[TestSequence]
AS [BIGINT]
START WITH 1
INCREMENT BY 1
GO
Change 1 in START WITH 1 with MAX value for [misc_id] + 1.
Usage:
INSERT INTO misc (misc_id, misc_group, misc_desc)
VALUES (NEXT VALUE FOR TestSequence, '#misc_group#','#misc_desc#')
My database is SQL Server. I want to insert a duplicate key in RequestId, then come across this error.
In addition:My database is created by Visual Studio Sql Server 2008 Server Project
I'm sure there is no constraint in the table.
Neither a column is PRIMARY KEY:
CREATE TABLE [dbo].[RequestPrize] (
[RequestId] INT NOT NULL,
[PrizeId] INT NULL,
[Verified] BIT NOT NULL,
[Created] SMALLDATETIME NOT NULL
);
But when I insert a duplicate key of RequestId:
insert into [RequestPrize] (RequestId, PrizeId) values('138', 9)
error output :
Violation of PRIMARY KEY constraint 'PK_RequestPrize'. Cannot insert duplicate key in object 'dbo.RequestPrize'.
Then I try to drop this constraint,
ALTER TABLE [RequestPrize] DROP CONSTRAINT RequestId
error :
Msg 3728, Level 16, State 1, Line 1
'RequestId' is not a constraint.
Msg 3727, Level 16, State 0, Line 1
Could not drop constraint. See previous errors.
update:
I really want to know where this CONSTRAINT come from.
Without PK all works fine -
CREATE TABLE dbo.RequestPrize
(
[RequestId] INT NOT NULL,
[PrizeId] INT NULL,
[Verified] BIT NOT NULL DEFAULT 0,
[Created] SMALLDATETIME NOT NULL DEFAULT GETDATE()
)
GO
INSERT INTO dbo.RequestPrize (RequestId, PrizeId)
VALUES (138, 9)
GO
INSERT INTO dbo.RequestPrize (RequestId, PrizeId)
VALUES (138, 9)
GO
So drop (if exist) your PK -
IF EXISTS(
SELECT 1
FROM sys.objects o
WHERE o.type = 'PK'
AND o.parent_object_id = OBJECT_ID('dbo.RequestPrize', 'U')
) ALTER TABLE dbo.RequestPrize DROP CONSTRAINT PK_RequestPrize
To drop a constraint you have to use the alias name for constraint you specified while creating "PK_RequestPrize".
By Syntax i guess you are using Microsoft SQLserver, to be sure check if query browser is connected to proper DB.
use "[dbo].[RequestPrize]" while inserting to have more confirmation.
In SQL Server 2008 R2, I am looking to create a trigger that imitates the behavior of an Oracle BEFORE INSERT trigger, where any insert that comes in has the trigger update the UPDATE_TS and CREATE_TS to the current timestamp right before the persist.
To issue I am seeing right now is the error:
An explicit value for the identity column in table 'MY_TABLE' can only be specified when a column list is used and IDENTITY_INSERT is ON
I am not sure if it is a good idea to turn SET IDENTITY INSERT table ON and then
SET IDENTITY INSERT table OFF within the trigger. Maybe that is a possible solution.
Please advise on best practice.
Example Table is called MY_TABLE:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
[CREATE_TS] [datetime] NULL,
[UPDATE_TS] [datetime] NULL),
PRIMARY KEY (MY_TABLE_ID))
Trigger:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE([MY_TABLE_ID], [FIELD_TO_UPDATE], [CREATE_TS], [UPDATE_TS])
SELECT i.MY_TABLE_ID, i.FIELD_TO_UPDATE, GETDATE(), GETDATE()
FROM INSERTED as i
END
Not sure why you are using dynamic SQL, it's not really needed. Also, no need to do an UPDATE afterwards, you can just do:
CREATE TRIGGER my_table_create_ts_trigger
ON [mydb].myschema.MY_TABLE
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO MY_TABLE(<list of every non identity column here>)
SELECT <list of every non identity column and the date here>, GETDATE()
FROM INSERTED
END
Also, you should list the columns explicitely in the INSERT and the SELECT.
I must be a glutton for punishment, but I have a better suggestion. Drop the trigger.
Change your table to:
CREATE TABLE [myschema].[MY_TABLE](
[MY_TABLE_ID] [bigint] IDENTITY(1,1) NOT NULL,
[FIELD_TO_UPDATE] [varchar](255) NOT NULL,
-- change this column to have a default:
[CREATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- and this column too, I guess:
[UPDATE_TS] [datetime] NOT NULL DEFAULT CURRENT_TIMESTAMP),
PRIMARY KEY (MY_TABLE_ID))
Why would you allow those columns to be NULL? Why do you want to use an elaborate trigger to replace something that is much simpler to implement with a default constraint?
You don't need the trigger, and I don't understand what benefit it brings or why you want to replicate a BEFORE trigger. An INSTEAD OF trigger is similar, but not exactly the same thing.