How to set a primary key using SQL - sql

I have this table 'Cars', attributes:
MODEL nvarchar(20)
STYLE nvarchar(20)
ENGINE nvarchar(5)
CAPACITY smallint
MAX_SPEED smallint
PRICE smallmoney
MARKET nvarchar(20)
COMPETITOR nvarchar(20)
I would like to set 'PRICE' as the primary key via a SQL sStatement, so I've tried:
ALTER TABLE Cars
ADD PRIMARY KEY (PRICE)
But I just get the error
The ALTER TABLE SQL construct or statement is not supported.
in Visual Studio 2010.

As has been said above, price is a bad primary key. But ... the correct syntax to do what you are trying to do is:
ALTER TABLE Cars
ADD CONSTRAINT cars_pk PRIMARY KEY (PRICE)

Visual studio is not a database client. If you want to run any query at all, you have to use a client that allows you to do so. The details depend on the database engine you are using.
If you want to do this with Visual Studio, you have to send that command, as a query, the same way you would send a select query. Once again, the details depend on your database engine.
Something else that depends on the database engine is the syntax of the command itself. Some will allow what you tried. Other will make you use the constraint keyword.
Finally, as mentioned in the comments, price is a poor choice for the primary key. Better choices would be a uuid, an autoincrementing integer, or, the VIN.

Related

Entity Framework Database First approach in Azure

I have a bunch of SQL scripts that create my database. I'd like to use the Database First approach with EF and Azure. I figured out that there are certain fields that my tables need to include:
CREATE TABLE dbo.Company
(
[Id] VARCHAR(50) NOT NULL CONSTRAINT DF_Company_Id DEFAULT '0',
CompanyName NVARCHAR(50) NOT NULL CONSTRAINT DF_Company_Name DEFAULT '',
-- Azure properties
[Version] TIMESTAMP NOT NULL,
[CreatedAt] DATETIMEOFFSET(7) NOT NULL,
[UpdatedAt] DATETIMEOFFSET(7) NULL,
[Deleted] BIT NOT NULL
)
I also figured out that I need certain constraints on these fields:
ALTER TABLE dbo.Company ADD CONSTRAINT PK_Company PRIMARY KEY NONCLUSTERED ([Id] ASC);
GO
ALTER TABLE dbo.Company ADD CONSTRAINT DF_Company_CreatedAt DEFAULT CONVERT(DATETIMEOFFSET(7), SYSUTCDATETIME(), 0) FOR [CreatedAt]
GO
ALTER TABLE dbo.Company ADD CONSTRAINT DF_Company_Deleted DEFAULT 0 FOR Deleted
GO
CREATE CLUSTERED INDEX IX_Company_CreatedAt ON dbo.Company([CreatedAt] ASC)
GO
CREATE TRIGGER [TR_Company_InsertUpdateDelete] ON dbo.Company
AFTER INSERT, UPDATE, DELETE AS
BEGIN
UPDATE dbo.Company
SET dbo.Company.[UpdatedAt] = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
FROM INSERTED WHERE inserted.[Id] = dbo.Company.[Id]
END
GO
I'm wondering if there is any documentation for that. I'm not sure if I included all fields and constraints. Also, I'm not sure if creating tables using a SQL script like the above one is a good approach for EF with Azure.
Any advice?
===UPDATED TO CLARIFY THE QUESTION===
Maybe it would be clearer to explain my question step-by-step:
I have a bunch of SQL scripts that create database structure.
I'd like to make the database structure usable by Azure. For example, Azure has Offline Data Sync feature that I know requires certain fields in the tables.
Through trial and error, I have found that Azure uses certain fields (Version, CreatedAt, UpdatedAt, and Deleted) and triggers to provide its features (such as Offline Data Sync).
I modified my SQL scripts to include this "Azure-specific" fields and triggers.
The problem is the "trial and error" part. It's just wrong to apply such an approach in production code that potentially will be used by many users. I'd like to find out what exactly Azure needs in the database. When the database is created using Code First all the "plumbing" is created by Azure. With the Database First approach, I have to create this plumbing. I'm wondering if I did not miss anything.

Can't create graph tables with sqlproj

After getting really fed up with using hierarchyids to manage my node tree, I decided to take a stab at using SQL Server 2017's graph functionality to ease my troubles.
I have a little bit of confusion, though. Currently, all of my SQL scripts are stored and organized in a SQL database project. When I create a node table and publish it to my Azure SQL Database, it only creates a standard table.
However, I can paste the exact same query into SSMS and it creates the graph table just fine. I've included the query below. Am I missing anything obvious?
CREATE TABLE [dbo].[GraphSite]
(
[SiteId] UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
[SiteName] NVARCHAR(100) NOT NULL,
[SiteTypeId] UNIQUEIDENTIFIER NOT NULL,
[SiteTimeZone] NVARCHAR(20) NOT NULL DEFAULT N'America/New_York',
[SiteStatusId] UNIQUEIDENTIFIER NULL,
[SiteThemeId] UNIQUEIDENTIFIER NULL,
CONSTRAINT [PK_GraphSite] PRIMARY KEY ([SiteId]),
CONSTRAINT [FK_GraphSite_SiteType] FOREIGN KEY ([SiteTypeId]) REFERENCES [SiteType]([SiteTypeId]),
CONSTRAINT [FK_GraphSite_SiteStatus] FOREIGN KEY ([SiteStatusId]) REFERENCES [SiteStatus]([SiteStatusId]),
CONSTRAINT [FK_GraphSite_SiteTheme] FOREIGN KEY ([SiteThemeId]) REFERENCES [SiteTheme]([SiteThemeId])
) AS NODE;
EDIT: I installed SQL Server 2017 locally and it leaves "AS NODE;" in fine. So SSDT seems to have an issue building graph tables to Microsoft Azure SQL Database v12. Which is weird, considering Azure SQL databases fully support graph tables. Any thoughts?
Could you try downloading the latest version of SSDT from here: https://learn.microsoft.com/en-us/sql/ssdt/download-sql-server-data-tools-ssdt
This should fix the problem for you.

Create field constraint based on another table field in LibreOffice Base

I have 3 tables, "Courses"(id, start_date), "Subscriptions"(id, assistant_id, course_id, date) and "Assistants"(id, registration_date).
Subscriptions reference Courses and Assistants with foreign keys as you see.
I need to add CHECK constraint that will prevent to create Subscription record if referenced Courses.start_date is older than referenced Assistants.registration_date. Is there a way to do this in Libre Base?
Table organization could not be changed.
Such a CHECK constraint cannot be created with the default engine. From the HSQLDB 1.8 documentation:
ALTER TABLE <tablename> ADD [CONSTRAINT <constraintname>]
CHECK (<search condition>);
Adds a check constraint to the table. In the current version, a check constraint can reference only the row
being inserted or updated.
This means that commands like the following from TestSelfCheckConstraints.txt produce an error:
/*e*/CREATE TABLE TC6(A CHAR, B CHAR, C CHAR, D INT, CHECK(A IN (SELECT A FROM
TC5)));
So, to perform such a check, you will have to verify it ahead of time (or afterwards) using a query. This could be done for a form by adding a macro in the Events tab. See this post for ideas: https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=21414.
The default engine is rather old, so for such complex requirements it may be better to set up LibreOffice Base to use a different database engine. For example using MySQL, it is possible to set up a stored procedure trigger to do this kind of checking. See CHECK constraint in MySQL is not working.

How to alter SQL Table default data type during design

I would like to change the default data type when designing a table in SQL Server Management Studio Table Designer. My current default is nchar(10) and I am creating a table with a lot of integer data types. I looked in Tools Options but could not find anyplace to change this. I'm running SQL Server 2008 R2.
It is possible, but requires a modification of the registry.
This is a tiresome change to make every time you wish to change the default, so I agree with NYCdotNet.
HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\100\Tools\Shell\DataProject
It sounds like you're ready to create your table using T-SQL and not the designer. A variation of the below code will cover you for putting together a basic schema and if you want to do more stuff you can always revise the table in the designer later.
CREATE TABLE MyTableName (
MyID INT NOT NULL IDENTITY(1,1),
MyColumn1 INT NOT NULL,
MyColumn2 INT NULL,
MyColumn3 VARCHAR(100) NULL,
PRIMARY KEY (MyID)
)
UPDATE: My apologies, read your question too fast. This solution is for the visual designer in VS2015, not SQLSMS. I will leave the answer up anyway.
This has been changed in Visual Studio 2015. It is now in:
Options > Database Tools > Table and Database Designers > Column Options

What is the effect (or purpose) of a foreign key column referencing itself?

During a database migration, I've run across a database table constraint of the form:
ALTER TABLE [dbo].[myTable]
ADD CONSTRAINT [someName] FOREIGN KEY ([id]) REFERENCES [dbo].[myTable] ([id])
ON DELETE NO ACTION
ON UPDATE NO ACTION
Why would one do this? This was originally done on a Sybase database, and we are converting to SQL Server 2008 R2.
UPDATE: Yes, the foreign key constraint is a field referencing the same table AND SAME FIELD.
I ran this query on the source Sybase database and found 42 of these crazy keys defined, so it doesn't seem like a typo.
SELECT sr.constrid as [Constraint ID],
so.name as [Table],
sc.name as [Column]
FROM sysreferences sr
INNER JOIN sysobjects so ON (so.id = sr.tableid)
INNER JOIN syscolumns sc ON (sc.id = sr.tableid AND sc.colid = sr.fokey1)
WHERE sr.tableid = sr.reftabid
AND sr.fokey1 = sr.refkey1
AND sr.fokey2 = 0
AND sr.refkey2 = 0
I believe that hierarchies are the standard examples you'll find in books whenever you use foreign keys for the same table, such as:
create table Employees (
EmployeeID int identity primary key,
EmployeeName varchar(50),
ManagerID int
Foreign key (managerID) references Employees(EmployeeID)
)
What you posted looks like a wrong application of this hierarchy relation in the same table. I'm not entirely sure why you'd ever wanna do that.
Hope this helped =)
Surprise! This totally works:
create table crazy (
ID int primary key references crazy (ID) -- This runs
);
insert into crazy select 1; -- So does this
select * from crazy; -- Returns 1
truncate table crazy; -- Works just fine
I can only think that this would have been a mistake (Typo? Dragging a column onto itself in a diagram?) or used to fool another system (ORM?) into some particular behavior. I will be very curious to see if someone comes up with a legit reason.
UPDATE: As cleverly suggested by #8kb, this could have been an attempt to prevent truncation, but we can see from my example that even truncation works just fine.
I guess it's a bug in database model.
It's really weird. I can't imagine what usefull purpose is this construction.
The only way how to insert data is without checking reference integrity. It means with explicitly disabled references or with some kind of bulk insert and so on.
The effect of a foreign key column referencing itself seems to be nothing. It is still an outstanding question as to why a database engine would let you do such a useless thing.
However, I believe the reason someone would build a foreign key like this is laziness / carelessness. I found out that in SQL Server Management Studio, if you build a foreign key using the GUI (instead of writing it out in T-SQL), the initial behavior of SSMS is to create foreign key exactly like in this question:
Expand any table of a database in the Object Explorer pane. We will call this table TableA.
Rt-click on Keys under the TableA node and select New Foreign Key... This will open the Modify table pane and the Foreign Key Relationships dialog.
Changing nothing, simply click the Close button on the Foreign Key Relationships dialog. "Oops, I didn't mean to try to add a foreign key."
Closing the dialog still generated a foreign key with the name FK_TableA_TableA and picked the primary key column as both the base and reference column.
With the Modify table pane still open (which it still is after closing the Foreign Key Relationships dialog), close it. It has changes (the new foreign key you just made). Save these changes.
A new foreign key now exists in the database for TableA, with the primary key column referencing itself.