GUIDs in SQL Server - c#

I have an ASP.NET application that generates GUIDs in the code-behind via C#. These GUIDs are generated via the following:
Guid id = Guid.NewGuid();
This GUID is later stored in a SQL Server 2008 database. I also have a stored procedure that will update that record. I would like to generate a GUID in the stored procedure that is in the same format as the one generated in ASP.NET.
Can somebody please tell me how to do this?
Thank you!

Use NEWID() method
DECLARE #ID uniqueidentifier
SET #ID = NEWID()

If this is for a clustered index (most often a primary key), I highly recommend NEWSEQUENTIALID() (SQL Server 2005 on up) since, NEWID() will create a fragmented index in that case, being truly random.

This will generate a GUID for you: SELECT NEWID()
Examples may be found here: http://msdn.microsoft.com/en-us/library/ms190348.aspx

My guess from the way that you have worded your question is that you are storing the GUIDs in a text (e.g. VARCHAR) field in the database - if this is the case then you should instead be using the uniqueidentifier type in which case you can use the NEWID() SQL function to generate a new GUID.
See C# guid and SQL uniqueidentifier for more detail on how to store GUIDs in an SQL Server database.

You could use NEWID().
But, there are issues with indexing guids generated like this. Instead, you should use the comb algorithm:
CAST(CAST(NEWID() AS BINARY(10)) +
CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)
Make sure you are storing these in a column of type UNIQUEIDENTIFIER and not converting them to NVARCHAR or anything of the sort.

You can use the NEWSEQUENTIALID for better indexing support, but the downside is that you can use this function only as a default value expression for your column.
You can use something like:
INSERT INTO MyTABLE (...) OUTPUT inserted.GUIDCOLUMN INTO #tableVar VALUES (...)
to access the newly generated sequential id.

Related

Changing ntext to nvarchar using C# and Entity Framework

I have to add sorting to existing database created in SQL Server. The problem is that this database contains ntext columns that are not supported by LinQ's OrderBy method. The database was written in a code-first approach, so I have access to template of database, but I can't look at ready database working on the server.
I've tried to change string type properties marking them as
[Column(TypeName = "nvarchar(MAX)")]
but then I got a
Sequence contains no matching element
exception which I don't know how to fix.
This is the way that I wanted to sort my data(i got exception right in the below instruction:
MyDatabase.MyTable.OrderBy(x => x.MyRow).Load();
Before I changed TypeName to nvarchar, I've got this error:
Large objects (ntext and image) cannot be used in ORDER BY clauses
Can somebody help me with fixing things up to make possible to sort data from database?
I'll appreciate any kind of help. Thanks in advance!
In T-SQL you can solve this in many ways, may be you can adopt one of them for you too?
ORDER BY (cast MyTextCol as nvarchar(max))
create a view from
this table with that field casted as nvarchar(max) and use it
instead of your table(even in future)
ALTER TABLE myTable ALTER
COLUMN myTextCol nvarchar(max)
The last one solves your problem and takes no time to be made: it's just a metadata operation, nothing will reorganizen in your table for existing rows

Stored procedure to generate auto incremented string primary key

I just started with stored procedures and I want to create a string primary key with a constant part and an auto-incremental part. For example "REP101, REP102" REP103 ...".
Other methods that I found were to have two columns,an auto incremental int column and a primary key column with REP as a prefix. But I think it will be more efficient if I used stored procedures.
I am looking for a way of retrieving the last row in a table and returning its key using stored procedure so I can use it in the C# code. Any other way that can achieve the same result will be appreciated.
It seems to me that if every primary key value is going to have 'REP' as the prefix, then you really don't need the prefix at all, and you can simply use an Identity column as your primary key. Then you don't need a stored procedure at all, and this will be much more efficient.
A stored procedure would be more efficient. You'd use a Sequence to create the numeric part and then return it concatenated with the prefix.
roughly:
CREATE PROCEDURE GetNextKey
#key VARCHAR(50) OUT
AS
BEGIN
SET #key = 'REP' + SELECT NEXT VALUE FOR keys_seq;
END;
However, why bother with the prefix in your primary key at all? Take a closer look at your design and htink it you really need to make the distinction. You can simply use a auto-increment ID as your primary key and add the prefix at point of display, if necessary.

Insert statement when having GUID as primary key

Is there a way to insert a row in SQL CE using the INSERT Statement when I have a GUID field.
In C#, I use
ID = Guid.NewGuid()
But in SQL console I can't find a keyword to do this.
I've found just this one :
> Insert into Customer (ID, Name) values ('f5c7181e-e117-4a98-bc06-733638a3a264','MyCustomer')
What about if I have a lot of rows to insert ?
try to use Newid() in Sql server to generate GUID
Can't you use NEWID() function?
To have a GUID on a field you can set the default of a column to be NEWSEQUENTIALID(). So, for example:
CREATE TABLE tableName (
Guid UNIQUEIDENTIFIER DEFAULT NEWSEQUENTIALID(),
Name VARCHAR(100)
);
Then insert into the table by executing the following query:
INSERT INTO tableName (Name) VALUES ('Test');
I'm not sure if NEWSEQUENTIALID() is supported in CE or not, as I've never used CE for development.
In C#, GUID are lower case so use LOWER(NEWID()) in SQL if you want them to look similar.

C# : Is there any C# function to insert primary key from one table into another

I have 2 tables in which i want to insert data one after another. The primary key of first table is in the 2nd. Is there any C# function so that i can insert the primary key of first table into another at 1 go, without any select query?
You can accomplish it with a stored procedure that performs both inserts and returns the identity value to the caller.
CREATE PROCEDURE procedure1
AS
BEGIN
DECLARE #id int;
INSERT INTO [table1] (col1) VALUES ('Foo');
SET #id = SCOPE_IDENTITY();
INSERT INTO [table2] (col1, col2) VALUES (#id, 'Bar');
RETURN #id;
END
You might look at using the OUTPUT clause in your insert statment.
Not sure if I understand your question but I think you want to know the primary key without consulting the server.
It this case you need to use guid's as the primary key which can be generated client side in C#. Identity columns won't work as they are generated by sql server.
Or you you could create a stored procedure that does the insert for you at the server and leave the identities at the client empty.
Update 1
To get the latest generated identity from sql server you can use
SCOPE_IDENTITY
(This is equivalent to mysql_insert_id() )
There are some other options namely
##IDENTITY
SCOPE_IDENTITY()
IDENT_CURRENT
Which you can read up on at http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

How do I get the C# Query component to recognise columns returned data from a temporary table in a sql stored procedure

I've created a stored procedure similar to the one below (I'm using this cut down version to try and figure our the problem).
CREATE PROCEDURE bsp_testStoredProc
AS
BEGIN
CREATE TABLE #tmpFiles
(
AuthorName NVARCHAR(50),
PercentageHigh INT
)
-- Insert data into temp table
SELECT AuthorName, PercentageHigh FROM #tmpFiles
ORDER BY PercentageHigh DESC
DROP TABLE #tmpFiles
RETURN 0
END
From my C# code in VS2008, I'm trying to use the Query component with the Use Existing Stored Procedure option to connect this up to a DataTable / DataGridView to display the results.
However, because I'm selecting from a temporary table, in the Query component properties Visual Studio does not display any columns being returned from the stored procedure. I assume that it has trouble determining the data types being used since the SP is not based on a real schema.
Connecting to different stored procedures that select from real tables do show the columns correctly.
Does anyone know away around this? Is there some sort of hint I can add somewhere to explicitly state what sort of data will be returned?
Thanks in advance.
For info, you might consider using a "table variable" rather than a temporary table (i.e. #FOO rather than #FOO) - this might help a little, and it certainly helps a few tempdb issues.
With temporary tables - no there is no way of explicitly declaring the SPs schema. I would perhaps suggest using a simplified version of the SP while you generate your wrapper classes - i.e. have it do a trivial SELECT of the correct shape.
Alternatively, I would use LINQ to consume a UDF, which does have explicit schema.

Categories

Resources