Understanding the populating of Tables - sql

I'm trying to understand how to populate Tables and have been given some code by my professor. I can't tell why these two statements are different in their Syntax:
Q1:
Insert into SecurityType (SecurityTypeCode, SecurityTypeDesc)
Values ('STO', 'Stock');
INSERT INTO [Country] ([CountryId], [CountryCode], [CountryDesc]) VALUES (-1, N'NOT SPECIFIED', N'Not Specified')
That is after looking at the two statements above, can we write the first statement as
Insert into SecurityType ([SecurityTypeCode], [SecurityTypeDesc])
Values ('STO', 'Stock');
Q2:
My professor says "You need to set Idenitity insert ON in order to insert a value into an identity column". I'm unclear as to what an "identity column" is.
Thanks

1) Column names can be wrapped in brackets, this is done if your column name is a reserved key word or your column name has spaces.
So you can have the brackets around the column names and it is same as first statement.
2) Identity column values automatically generated and you use this syntax to create such a column
CREATE TABLE Employee
(
id int IDENTITY(1,1)
SQL server doesn't allow you to insert a value for this identity column, in case you want to insert a default value or some values , you can set identity insert ON.

Related

Insert query: Column name or number of supplied values does not match table definition

This is a table that auto increments the ID, takes the time input, and sets the default of the total column as zero and the date column with getdate()
CREATE TABLE OrderPlaced (
OrderID bigint IDENTITY(1,1) PRIMARY KEY,
PlacedAt time NOT NULL,
PlacedOn DATE NOT NULL default getdate(),
Total MONEY default 0
)
So the only value that I have to insert is the time.
insert into OrderPlaced values ('13:40');
However on insertion SQL Server gives me this error:
Column name or number of supplied values does not match table definition.
The error is telling you the problem. Your table, OrderPlaced, has four columns, but you only supply one column in the INSERT and don't tell the instance what column to insert it into.
For your table, if you don't specify the columns then it will expect values for PlacedAt, PlacedOn and Total; it won't expect a value for OrderID as it is an IDENTITY and you haven't turned on IDENTITY_INSERT. As the instance is expecting 3 columns, and you only provide one, you get an error telling you that the number of columns don't match (3 != 1).
If you only want to insert a value into PlacedAt, and allow the rest of the columns use their DEFAULT values then define in your INSERT clause you only want to provide a value for PlacedAt:
INSERT INTO dbo.OrderPlaced(PlacedAt)
VALUES ('13:40');
Or, if you are (oddly) opposed to defining the columns in the INSERT clause, then tell the instance that the other 2 columns need their DEFAULT values.
INSERT INTO dbo.OrderPlaced
VALUES ('13:40',DEFAULT, DEFAULT);
Though I don't recommend this solution, be explicit as then if you change definition of the table, the above statement will fail.
You need to specify the column name as well, like this:
INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);
So it will be like this:
insert into OrderPlaced values ('13:40');

When inserting a tuple into a table in SQL, does the order of the attributes in the schema matter?

ie. if Students(id,name,major,gpa) is the schema, are the following 2 SQL queries valid?
INSERT
INTO Students(id,name,major,gpa)
VALUES (123, Joe, CPSC, 3.0)
INSERT
INTO Students(name,id,major,gpa)
VALUES (Mike, 505, CPSC, 4.0)
Yes both of the query are correct. And the Values will insert to the column in whatever format your INSERT INTO t_Tablename(column1,column2) is made.
Just to make a check you can do (Assume id is int and Name is varchar)
INSERT INTO Students(id, Name)
VALUES("testString", 1)
which will give you an error, since you're trying to insert a string value to id which accepts an int and vice versa
Yes, the two following queries are Valid. Since you keep the order of your attributes values as described in Students(column1,column2), the query will be ok.
As long as the order in the INTO expression equates to the order in the VALUES expression, that is all that is required. The column list in the INTO expression determines both which columns you're specifying values for and the order the values will appear in the VALUES expression. The first column gets the first value, the second gets the second value, and so on.
If you neglect to specify the column list in the INTO expression, most RDBMSs will assume that the columns in the VALUES expression are in the ordinal order of columns in the table itself. That is, if you do this:
INSERT INTO Students
VALUES (123, Joe, CPSC, 3.0)
Then you better have done something like this:
CREATE TABLE Students (id int, name varchar(30), major varchar(30), gpa numeric(3,2))
That's the only time that the order of columns in the table itself actually matters to an INSERT statement.

Copying values / columns from one table to another existing tabler in SQL Server Management Studio

I want to copy all columns from dbo.die to dbo.technology.
Both tables exist! In dbo.technology, the primary key is idTechnology
In dbo.die, the primary key is idDie and we have a foreign key, which is Technology_idTechnology in it, which connects the die table with the technology table.
How could I do that, so that the values got copied to the right rows, which match the same idTechnology?
I tried this:
INSERT INTO dbo.die
(Technology_idTechnology, Technology_D, Technology_Type, Technology_Manufacturer, Technology_SOI, Technology_Node, Technology_Name, Technology_Number_Metal, Technology_Number_Poly, Technology_Power_Cu, Technology_FEComplexity, Technology_FEComplexity_Sec, Technology_Trench, Technology_IMID, Technology_Remarks)
SELECT *
FROM dbo.technology tech
WHERE tech.idTechnology = idTechnology;
but I'm always getting an error!
Cannot insert duplicate key row in object 'dbo.die' with unique index 'ui_dieIdsample'. The duplicate key value is ().
Don't know what I should do.. I thought it's easy & simple
If a column is declared as NOT NULL (and has no default value), a value for the column must be specified in the INSERT statement.
In this specific case you should add Table2_Feld to the insert column list, and specify a value in the SELECT for it!
You will need to change your column list (lets say that its acceptable to insert a default value of 0 into column Table2_Feld)
INSERT INTO dbo.table2
(Table1_idTech, Tech_D, Techn_Type, Tech_Man,
Techn_Node, Tech_Name, Technology_Numb, Tech_Po,
Tech_FEC, Techn_Comp_Sec,
Tech_R,Table2_Feld)
select *,0 from table1 tech

Can't INSERT INTO SELECT into a table with identity column

In SQL server, I'm using a table variable and when done manipulating it I want to insert its values into a real table that has an identity column which is also the PK.
The table variable I'm making has two columns; the physical table has four, the first of which is the identity column, an integer IK. The data types for the columns I want to insert are the same as the target columns' data types.
INSERT INTO [dbo].[Message] ([Name], [Type])
SELECT DISTINCT [Code],[MessageType]
FROM #TempTableVariable
This fails with:
Cannot insert duplicate key row in object 'dbo.Message' with unique index
'IX_Message_Id'. The duplicate key value is (ApplicationSelection).
But when trying to insert just Values (...) it works ok.
How do I get it right?
It appears that the data "ApplicationSelection" is already in the database. YOu need to write the select to exclude records that are already in the database. YOu can do that with a where not exists clause or a left join. LOok up teh index to see what field is unique besides the identity. That will tell you what feild you need to check to see if teh record currently exists.

Inserting rows into a table with one IDENTITY column only [duplicate]

This question already has answers here:
How to insert into a table with just one IDENTITY column?
(5 answers)
Closed 1 year ago.
I have a table Administrator with only one column, adminId which is the primary-key. Because of business rules it has to be this way.
I'd like to understand once and for all how I can write stored procedures that insert values in tables like this. I am using SQL Server and T-SQL and tried using SCOPE_IDENTITY() but that doesn't work since the table has INSERT_IDENTITY to false or off.
I'd really like to not insert a dummy value just to be able to insert a new row. Thanks!
If you have one column that is an IDENTITY, just do this
INSERT MyTable DEFAULT VALUES; --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();
If you don't have identity, then can you set it? This is the best way.. and use the SQL above.
If not, you want to insert a new row
INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable
Notes:
Under high loads the MAX solution may fail with duplicates
SCOPE_IDENTITY is after the fact, not before
SCOPE_IDENTITY only works with an IDENTITY column. Ditto any idiocy using IDENT_CURRENT
The output clause replaces SCOPE_IDENTITY for the MAX solution
You need to add the IDENTITY_INSERT to your select statement:
SET IDENTITY_INSERT MyTable ON
INSERT INTO MyTable
(AdminCol)
SELECT AdminColValue
FROM Tableb
When you're done, make sure you remember to
SET IDENTITY_INSERT MyTable OFF
Here's a good description of how it works from BOL: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx
#Phil: Don't you mean your table has two(2) columns, the autoincrementing PK column and an AdminName column? If it only has one column where the AdminName goes, the AdminName is the PK and you cannot autoincrement a string, of course. Do the business rules expect you to make a fully-qualified Windows username the primary key? That would be viable and make sense, because then you wouldn't need an alternate unique index on the AdminName column.
But if your table has two columns, not one:
In SQLServer the autoincrement is part of the table/column definition. You define the column as an integer and then also make it an
identity column, specifying the increment, usually 1, but it could be 2 or 5 or 10 or whatever. To insert a row, you simply insert the other column(s) value(s) and do nothing with the PK column:
insert into T
(foo) -- column(s) list
values('bar') -- values list
Your stored proc that does the insert can make SCOPE_IDENTITY a RETURN value or SCOPE_IDENTITY can be passed back to the client as an OUT parameter.
P.S. SCOPE_IDENTITY() returns the most recently generated autoincremented identity value in the current scope; it does not generate the next identity value.
EDIT:
Presumably, your Administrators table contains a set of administrators. But if it has no columns whatsoever other than the integer primary key column, there is no way to identify the administators; the only thing you can do is distinguish them from each other. That doesn't get you very far at all. But if your Administrator table had either of the following structures:
ID INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername varchar(50) (unique index)
OR
windowsusername varchar(50) primary key
you would be able to reference the Administrator's table from other tables, and the foreign keys would be MEANINGFUL. And that's precisely what a table consisting of a single integer column lacks -- meaning.
Having two columns, you could then have a stored procedure do this:
insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();
and your client-program would get back as a return value the autoincremented id that had been autogenerated and assigned to the newly inserted row. This approach is the usual practice, and I would go so far as to say that it is considered "best practice".
P.S. You mention that you didn't know how to "insert a value" if you "didn't have anything to insert". There's a contradiction there. If you have nothing to insert, why insert? Why would you create, say, a new CUSTOMER record if you know absolutely nothing about the customer? Not their name, their city, their phone number, nothing?