Change SQL Server primary key using C# - c#

I need to change a column type in a SQL Server table.
I need do it using a script or C#.
The original datatype is integer and the new type is varchar(50).
I can do it using this SQL script:
ALTER TABLE confezionamento ALTER COLUMN partnumber varchar(50)
but the problem is that this column is in a set of primary keys.
When I try do execute, an error occurred because PK_CONFEZIONAMENTO is using the column.
How I can do it without access to SQL Server Management Studio?

You will need to run SQL Commands to do the following steps:
Drop primary key constraint
Alter primary key
Add primary key constraint
If there are any foreign keys or indexes, you may have to deal with them as well.
The commands you are looking for will be similar to these:
Alter table confezionamento drop constraint PK_CONFEZIONAMENTO
ALTER TABLE confezionamento ALTER COLUMN partnumber varchar(50)
ALTER TABLE confezionamento ADD CONSTRAINT PK_CONFEZIONAMENTO PRIMARY KEY (partnumber)
These commands can all be sent from C# using ADO.Net or similar methods.

Related

Microsoft Sync Framework unique index error

I use the MS Sync Framework to sync my SQL Server instance with a local SQL CE file to make it possible working offline with my Windows app.
I use GUIDs as keys. On my table I have a unique index on 2 columns: user_id and setting_id:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
Now I do the following:
I create a new record in this table in both databases - SQL Server and SQL CE with the same user_id and setting_id.
This should work and merge the data together since this can happen in real life. But I get an error when syncing saying the unique key constraint led to an error. The key pair already exists in the table.
A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
Why can't MS sync handle that? It should not try to insert the key pair again. It should update the value if needed.
The issue is if you add the same key pair to different copies of the table, they get different IDs (GUIDs) as primary keys in this usersettings table.
As this is simply a many-to-many table between Users and Settings, there is no need to have that ID as a PK (or even a column at all).
Instead, just use a concatenated key of the two FKs e.g.,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
Of course, include appropriate field settings (e.g., if you use VARCHARs to store the IDs) and relevant FKs.
As the rows inserted should now be identical on the two copies, it should merge fine.
If you must have a single column as a unique identifier for the table, you could make it meaningful e.g.,
the PK (ID) becomes a varchar (72)
it gets filled with CONCAT(user_ID, setting_id)
As the User_ID and Setting_ID are FKs, you should already have them generated so concatenating them should be easy enough.
Do you get the error during sync, then it should appear as a conflict, that you must solve in code.
https://learn.microsoft.com/en-us/previous-versions/sql/synchronization/sync-framework-2.0/bb734542(v=sql.105)
I also see this in the manual: By default, the following objects are not copied to the client database: FOREIGN KEY constraints, UNIQUE constraints, DEFAULT constraints, and the SQL Server ROWGUIDCOL property. This indicates poor support for your scenario
I suggest you remove the unique constraint from the device table.

How to make sequential id number in SQL Server start form 1 like in an MS Access database

When I use Microsoft SQL Server database and make a filed's data type as uniqueidentifier and use the function newid() or newsequentialid(), it makes a new id that contain 32 value (hexadecimal value).
However, I need a way to make an auto-increment values starts with number 1 and so on just like auto-increment fields in MS Access.
Then I want to add other values using a C# program while the SQL Server adds the auto-increment field automatically without errors.
Note: I'm using SQL Server 2014, and Visual Studio 2015 perf.
You can use SQL Server method IDENTITY(1,1) to increment a column by 1 and starts from 1.
CREATE TABLE [dbo].[XXX](
[ID] [int] IDENTITY(1,1))
If you want the IncrementId also to be the primary key you can create your table like:
CREATE TABLE [dbo].[SomeTable](
[IncrementId] [int] IDENTITY(1,1) NOT NULL,
[OtherColumn] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED
(
[IncrementId] ASC
))
You than can insert values to the table like
INSERT INTO dbo.SomeTable (OtherColumn) VALUES ('SomeValue')
And this will give you a new row with an id that is the next in line so to speak
Create a Column and make it an identity column to the table
To create an identity column, you may use the Management Studio or u can write a query.
When Inserting data to the table, provide data to the columns, but not to the column created as identity column.
If you want to have an integer identity, you should use either TINYINT, SMALLINT, INT, or BIGINT column for your primary key. If you need GUID, you should use uniqueidentifier column type. You can't mix and match.
Regarding to the auto increment feature, if you need to insert a value manually, you should inactivate IDENTITY option on the table, insert your unique value, and then activate it again. I'm not really sure if it's a good idea to do this, but this is how it works:
-- Allows you to insert a value into identity column.
SET IDENTITY_INSERT [SchemaName].[TableName] ON;
-- Do you insertion here...
-- Deactivates the identity value insertion.
SET IDENTITY_INSERT [SchemaName].[TableName] OFF;

Linq to Sql Datacontext primary key not set

I created in my application a dataclasses context and want to insert in my database some entries via LINQ but it says
Can't perform Create, Update, or Delete operations on
'Table(discipline)' because it has no primary key.
But I already marked a column in the designer as identity column to true;
Can anyone please help?
Setting a column as IDENTITY doesn't mean that it is also the PRIMARY KEY of your table.
You need to set it explicitily using SSMS interface of through a sql statement
You can set it when creating the table:
CREATE TABLE Nations
(
NationID int IDENTITY(1,1),
Name varchar(255) NOT NULL,
CapitalCity varchar(255)
PRIMARY KEY (NationID)
)
or using the ALTER TABLE statement
ALTER TABLE Nations ADD PRIMARY KEY (NationID)

C# with SQLite and foreign key

I want to implement a patients data base for our software, and have an issue with the foreign key statement. I am using the latest SQLite DLLs, with C#.
When I try to run below code:
dbConnection = "Data Source=SQLiteMyDatabase.db;foreign keys=true;";
if (connections == 0)
{
cnn = new SQLiteConnection(dbConnection);
cnn.Open();
this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS patients ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) NOT NULL;");
this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS images ( FOREIGN KEY (patientID) REFERENCES patients(id), nameRed VARCHAR(20) NOT NULL PRIMARY KEY;");
}
I get the error:
SQLite error near "FOREIGN": syntax error
Why does this happen?
In order to create a foreign key, you must first create the column:
CREATE TABLE IF NOT EXISTS images (
nameRed VARCHAR(20) NOT NULL PRIMARY KEY,
patientID INT,
FOREIGN KEY (patientID) REFERENCES patients(id)
);
Please note:
I moved the primary key column (nameRed) first in the list of columns created, but that's just convention. It could go second.
You use the data type VARCHAR and SQlite will accept that, but be aware that it gets mapped to type TEXT, the maximum length will be ignored, and you will be able to store other data types in the column. SQLite is a bit funny when it comes to data types (it has a very well thought-out system but it's quite different from most other SQL databases).
To make things more confusing, you are allowed to declare the PRIMARY KEY as a property of the column (although you can also do it after the list of columns as with the FOREIGN KEY).

Entity Framework bug, insert command generation

I am working with PostgreSql DB using Entity Framework:
When I add new item into DB it generates strange code:
INSERT INTO (SELECT "person_contact"."person_id" AS "person_id",
"person_contact"."contact_id" AS "contact_id"
FROM "public"."person_contact" AS "person_contact")
("person_id","contact_id")
VALUES (cast(141792 as int8),cast(289406040 as int8))
So it add
SELECT "person_contact"."person_id" AS "person_id",
"person_contact"."contact_id" AS "contact_id"
FROM "public"."person_contact" AS "person_contact"
instead of table name "public"."person_contact"
How to resolve this Entity Framework bug ???
UPD: Same issue when I try to delete "person_contact" entry. In delete statement instead of table name - select query.
There are several ways to try and fix this:
Firstly, it could be that your model has become corrupt. You could try deleting the model and recreating it. Also see my answer to this question: SQL Server foreign keys messing with entity framework model
Secondly, you say that it only happens with this table. Is there anything special about this table.
Thirdly, you could try a different .net connector for ProgressSQL, see: http://www.devart.com/dotconnect/entityframework.html
These are listed in the order that I would try them.
Most likely you forgot to create primary key on this table.
I've had the same problem and the solution in my case was very simple. The problem was that I had a column named "id", but I forgot to make it Primary Key. The moment I set it as Primary Key everything was OK.
It is very strange, because EF, normaly won't import table without primary key, but when you have column named "id" it assumes that it is a primary key.
The structure of my table was:
*DROP TABLE IF EXISTS "public"."fact_season_tickets";
CREATE TABLE "public"."fact_season_tickets" (
"id" int8 DEFAULT nextval('fact_season_tickets_id_seq'::regclass) NOT NULL,
"season_ticket_id" int8 NOT NULL,
"date_key" int4 NOT NULL,
"station_id" int4 NOT NULL,
"amount" numeric(18,2) DEFAULT 0 NOT NULL,
"status" int4 NOT NULL
)
WITH (OIDS=FALSE)*
The generated by NpgSql INSERT statement was:
*INSERT INTO (SELECT "fact_season_tickets"."id",
"fact_season_tickets"."season_ticket_id",+
"fact_season_tickets"."date_key",
"fact_season_tickets"."station_id",
"fact_season_tickets"."amount",
"fact_season_tickets"."status"
FROM "public"."fact_season_tickets" AS "fact_season_tickets")
("season_ticket_id","date_key","station_id","amount","status")
VALUES (510::int8,20150630,2,18.00::numeric,1)
RETURNING "id"*
The solution was just creating a primary key:
*ALTER TABLE "public"."fact_season_tickets" ADD PRIMARY KEY ("id");*

Categories

Resources