Trouble with uniqueidentifier column - sql

I just started working with SQL Server and I have some troubles with adding values to a table with a column of type uniqueidentifier.
The table consists of:
ID (uniqueidentifier), CODE (nchar(5)), COUNTRY_CODE(nchar(2)), NAME(nchar30)
I tried adding values from Excel and CSV files, basically they look like this:
DEBE,DE,Berlin
I could not load it, always have some errors with this ID field.
When i try to add values manually like:
INSERT INTO [Portfolio].[dbo].[Regions](CODE, COUNTRY_CODE, NAME)
VALUES ('DEBE', 'DE', 'Berlin');
It says:
Cannot insert the value NULL into column 'ID', table
'Portfolio.dbo.Regions'; column does not allow nulls. INSERT fails.
Of course when I add an id column and a number, I get info that int is incompatible with uniqueidentifier.
I even tried creating a temp table (with id as an INT instead of uniqueidentifier) and copying values from it into this (without ID column, its supposed to generate automatically)
Only thing I can think of is that ID column is not creating values for it automatically and I don't know how to solve this. Can anyone help?

Uniqueidentifier is a special type you can use to generate GUID. Is 16 byte long and is not incremented automatically as the Identity columns. You need to use Convert or Cast clause in order to get the correct uniqueidentifier from a varchar, if it exceeds the 16bytes it will be truncated.
Use NewID() to generate a new uniqueidentifier.
Maybe this link can help you

As mentioned above, use NewID() to create an identifier.
When you are in the design mode for the table, NewID() can be placed in the 'Default Value or Binding' slot. This means that for any new record that you insert into the table (such as CODE, COUNTRY_CODE, NAME), a Unique Identifier will be created.

What I think you are looking for is an Identity field. The UniqueIdentifier field is used for storing GUID's.
Change the field type to int and then change it's Identity Specification to 'Yes".
The other solution would be to pass the ID field your own GUID from code.

Too late to answer, but it may help someone, go to you sql table design mode,
select your required table's attribute, here in detail tab (down to table) you'll see a property
RowGuid --> Yes (make sure to turn it to yes).
Cheers :)

Related

How to modify languageid column in a SQLite FTS table?

In SQLite FTS tables there is a hidden languageid column that I want to make use of: I need to populate my FTS4 table with rows in two different languages, which I will then distinguish by languageid column.
I create my table with a command like this:
CREATE VIRTUAL TABLE `texts` USING FTS4(`text`, tokenize=unicode61, languageid=`lid`)
Now how can I INSERT a row with a specified languageid if it is a hidden column? Or is there some other way to specify the language used in a row?
So, I had to explicitly specify the languageid column like this (here lid is the name of languageid column):
INSERT INTO `texts` (`text`,`lid`) VALUES (?,?)
Sidenote: I used Python in IntelliJ IDEA for this and the IDE gave me a Unable to resolve column 'lid' error, but the code still worked.

sql - retain calculated result in calculated field

certain fields in our database contain calculated functions e.g.
select lastname + ', ' + firstname as fullname from contact where contact.id =$contact$
when viewing the field the correct data is shown (i assume this is because when you open the record, the calculation is executed). however, the data is not 'stored' to the field, and therefore is null until the record is opened. is it possible to 'store' the result to the field, making it possible to search the data?
many thanks
james
EDIT
it is not possible for me to create computed_columns using our software.
the above field is a text feild where either 1) a user can manual type in the required data or 2) the database can generate the answer for you (but only whilst you are looking at the record). i know that if I run the following:
Select * from contact where contact.id =$contact$ for xml auto
i only get lastname, firstname - so i know that the fullname field does not retain its information.
If you are using computed columns in sql server, the column is already searchable regardless of whether the calculation result is stored or not. However, if you would like to make it so that the calculation is not run each time you read the row, you can change that under row properties in your Modify Table GUI.
Use the PERSISTED key word when you create the column
From BOL:
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table, and update the values when any other columns on which the computed column depends are updated. Marking a computed column as PERSISTED lets you create an index on a computed column that is deterministic, but not precise. For more information, see Creating Indexes on Computed Columns. Any computed columns that are used as partitioning columns of a partitioned table must be explicitly marked PERSISTED. computed_column_expression must be deterministic when PERSISTED is specified.
This isn't the way computed columns work in SQL Server, so I suspect this is something your client application is doing. How are you looking at the data when the value is computed correctly? Does it work when you view the data in SSMS?
Take a look at http://msdn.microsoft.com/en-us/library/ms191250(v=SQL.90).aspx to see how to create computed columns properly.
eg.
create table TestTable
(a int,
b int,
c as a + b)
insert into TestTable (a,b)
values (1,2)
select * from TestTable
where c = 3
This query is based on the computed column and it returns the row that's been inserted.
You need to use the PERSISTED option on a column when you use CREATE TABLE e.g.
CREATE TABLE test (col_a INT, col_b INT, col_c AS col_A * col_B PERSISTED)

How to get last inserted row in sql server

How can i get Last inserted row when in table there is no Uniqueidentifier or identity column.
I am waiting of your good idea's.
You need some way of being able to identify the ordering of the rows to determine that. Something like a "creation date" or IDENTITY column.
If you want to get last row from table without uniqueIdentifier or identity then you can use insert trigger.
You can't. A table consists of an unordered set of rows*. If you need to know, for instance, when a row was inserted, you need to add that information into the table definition (by adding a new column) and populating it appropriately.
*even in the face of a clustered index, it's healthier to always consider a table as being an unordered set of rows. A clustered index is useful, but it doesn't guarantee any particular physical ordering (As in Martin's comment to this answer)
Don't believe you can. You'll need some kind of identifier to extract data. ID, DateTime.. anything that will always be different from the others.
if you insert something by stored procedure you should use SELECT SCOPE_IDENTITY() which will return the last identity value created in the current session, but it will also limit it to your current scope.
By this usage you will not get last inserted identity which can be caused by trigger.
Have that in mind if you will use result for operation of insertion inside same or called procedure.
DECLARE #IDs TABLE(id int)
insert into TableName(TableID, TableRowValue)
output inserted.TableID into #IDs
values(857, 'Test');
-- The inserted identity will be in the #IDs table variable

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?

Share auto-incremented primary key between two tables

Hi I want to have two tables each have an INT "id" column which will auto-increment but I don't want either "id" columns to ever share the same number. What is this called and what's the best way to do it? Sequence? Iterator? Index? Incrementor?
Motivation: we're migrating from one schema to a another and have a web-page that reads both tables and shows the (int) ID, but I can't have the same ID used for both tables.
I'm using SQL Server 9.0.3068.
Thanks!
Just configure the identity increment to be >1 e.g. table one uses IDENTITY (1, 10) [1,11,21...] and table two uses IDENTITY (2, 10) [2,12,22...]. This will also give you some room for expansion if needed later.
I think using a GUID would be the most straightforward way, if I understand you correctly.
SELECT NEWID()
Use a column with GUID (Globally Unique Identifier) type. It's 16 byte and will be always unique for each row.
Just be aware that you'll get a significant performance hit comparing to normal integer keys.
Use another table with an ID key of type int default it to 1, called KeyID or whatever.
Have a stored procedure retrieve the value, add 1, then update the KeyID, then return this to the stored procedure which is updating your two tables which needs the new unique key.
This will ensure the ID is an int, and that it's unique between the set of tables which are using the stored procedure to generate new ID's.
You can define an IDENTITY column in a third table, use that to generate ID values, but you always roll back any inserts you make into the table (to avoid making it grow). Rolling back the transaction doesn't roll back the fact that the ID was generated.
I'm not a regular user of Microsoft SQL Server, so please forgive any syntax gaffes. But something like the following is what I have in mind:
CREATE TABLE AlwaysRollback (
id IDENTITY(1,1)
);
BEGIN TRANSACTION;
INSERT INTO AllwaysRollBack () VALUES ();
ROLLBACK TRANSACTION;
INSERT INTO RealTable1 (id, ...) VALUES (SCOPE_IDENTITY(), ...);
BEGIN TRANSACTION;
INSERT INTO AllwaysRollBack () VALUES ();
ROLLBACK TRANSACTION;
INSERT INTO RealTable2 (id, ...) VALUES (SCOPE_IDENTITY(), ...);
I don't know what you would call it.
If you don't want to use a GUID or a separate table, you could also create a function that looked at the max values of the ids from both tables and added one to the that value (or something like that).
You could then call that function in an insert trigger on both tables.
I am personally a fan of the GUID solution, but here is a viable option.
Many solutions to this problem have avoided GUID and used good old integer. This is common also with merge replication situations where many satellite sites merge with a master and key conflicts need to be avoided.
If GUID will not work for you, and you absolutely must have int, bigint, or the like, you can always just use an IDENTITY column and have each table with a different value for SEED. Those datatypes have a very wide range, and it is not too hard to split the range into usable segments, especially if all you want is two splits. As an example, basic int has a range from -2^31 (-2,147,483,648) through 2^31 - 1 (2,147,483,647). This is more than enough for a customer table, for example.
Transact-SQL Reference (SQL Server 2000)
int, bigint, smallint, and tinyint
Example:
--Create table with a seed of 1 billion and an increment of 1
CREATE TABLE myTable
(
primaryKey int IDENTITY (1000000000, 1),
columnOne varchar(10) NOT NULL
)
If you really need to do this with an int and you have an auto incrementing number, the way i have done this before is to change the id field auto increment function to the sequence of the other table. I am not too sure in ms sql or my sql but in pgsql that means that in the sql you would have this field
id integer NOT NULL DEFAULT nextval('table_two_seq'::regclass),
where table_two_sequence is the sequence function for the other table. Then test it out by inserting some data. I am really sorry if this wont work in ms sql i try to steer clear of it tbh. Failing that the GUID is the best way as has been mentioned by others. Or when inserting in the code that you use you could put an algorithm in that but it could get messy.
Alternatively, think about having the data in one table as this would be a way around it. if you need to you could have a view simulating two tables. Just a thought.
Hope i have helped
Starting with SQL Server 2012 you can declare a sequence object
https://msdn.microsoft.com/en-us/library/ff878091.aspx which is exactly what you need.
I should be pretty trivial to emulate a sequence object with a table
containing the next sequence value and a stored procedure atomically
select the value and increment. [You'd liked to use function, but functions
can't have side effects.]
How about this hack? Create a table (MySequence) with two columns: And Identity column (SequenceValue) and a dummy column (DummyValue) and use this stored procedure to get a new sequence value. The only row in the table will be last sequence value retrieved.
CREATE PROCEDURE GetNextValue
AS
BEGIN
DECLARE #value int = null;
-- Insert statements for procedure here
INSERT into MySequence (DummyValue) Values (null);
SET #value = SCOPE_IDENTITY();
DELETE from MySequence where SequenceValue <> #value
SELECT #value as Sequence
return #value
END
To use the sequence you'd have to manage the inserts to the target tables--a trigger would probably work.