How to generate and manually insert a uniqueidentifier in SQL Server? - sql

I'm trying to manually create a new user in my table but am finding it impossible to generate a "UniqueIdentifier" type without the code throwing an exception...
Here is my example:
DECLARE #id uniqueidentifier
SET #id = NEWID()
INSERT INTO [dbo].[aspnet_Users]
([ApplicationId]
,[UserId]
,[UserName]
,[LoweredUserName]
,[LastName]
,[FirstName]
,[IsAnonymous]
,[LastActivityDate]
,[Culture])
VALUES
('ARMS'
,#id
,'Admin'
,'admin'
,'lastname'
,'firstname'
,0
,'2013-01-01 00:00:00'
,'en')
GO
Throws this exception ->
Msg 8169, Level 16, State 2, Line 4
Failed to convert a character string to uniqueidentifier.
I am using the NEWID() method but it's not working...
http://www.dailycoding.com/Posts/generate_new_guid_uniqueidentifier_in_sql_server.aspx

ApplicationId must be of type UniqueIdentifier. Your code works fine if you do:
DECLARE #TTEST TABLE
(
TEST UNIQUEIDENTIFIER
)
DECLARE #UNIQUEX UNIQUEIDENTIFIER
SET #UNIQUEX = NEWID();
INSERT INTO #TTEST
(TEST)
VALUES
(#UNIQUEX);
SELECT * FROM #TTEST
Therefore I would say it is safe to assume that ApplicationId is not the correct data type.

Kindly check Column ApplicationId datatype in Table aspnet_Users , ApplicationId column datatype should be uniqueidentifier .
*Your parameter order is passed wrongly ,
Parameter #id should be passed as first argument, but in your script it is placed in second argument..*
So error is raised..
Please refere sample script:
DECLARE #id uniqueidentifier
SET #id = NEWID()
Create Table #temp1(AppId uniqueidentifier)
insert into #temp1 values(#id)
Select * from #temp1
Drop Table #temp1

Check your column data type should be unique identifier
And you are using the correct order when inserting values
INSERT INTO [dbo].[aspnet_Users]
([ApplicationId],[UserId],[UserName],[LoweredUserName],[LastName]
,[FirstName],[IsAnonymous],[LastActivityDate],[Culture])
VALUES ('ARMS',NEWID(),'Admin','admin','lastname','firstname,0
,'2013-01-01 00:00:00','en')

Related

Insert multiple rows using single insert statement

I am trying to insert into table variable using following query.
but its throwing an error.
Please help on inserting multiple selects using single insert statement.
DECLARE #AddressRecordsToPurge TABLE
(
RowID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
GUIDValue Nvarchar(max) ,
GuidColumn Nvarchar(max) ,
GuidTable Nvarchar(max)
)
Insert Into #AddressRecordsToPurge values ( (Select
EMPLOYMENTSEQUENCENUMBER FROM ACCOUNTANTSREFERENCE WHERE
CustomerNumber = #CustomerNumber AND Customerversionnumber =
#CustomerVersionNumber AND EMPLOYMENTSEQUENCENUMBER IS NOT
NULL), 'EMPLOYMENTSEQUENC ENUMBER', 'ACCOUNTANTSREFERENCE');
My select statement returns multiple values and I want to have it this way only. Please help!
Your syntax is slightly off:
Insert Into #AddressRecordsToPurge (GuidValue, GuidColumn, GuidTable)
SELECT EMPLOYMENTSEQUENCENUMBER, 'EMPLOYMENTSEQUENCENUMBER', 'ACCOUNTANTSREFERENCE'
FROM ACCOUNTANTSREFERENCE
WHERE CustomerNumber = #CustomerNumber
AND Customerversionnumber = #CustomerVersionNumber
AND EMPLOYMENTSEQUENCENUMBER IS NOT NULL;

Return inserted row from stored procedure

I have the following stored procedure
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
AS
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
SELECT #new_identity = SCOPE_IDENTITY()
SELECT * FROM NameAge where Id = #new_identity
Is there are a more efficient way to return the last inserted record complete with id and associated data?
Use Insertedwithin output clause,
As the follwoing:
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
AS
DECLARE #MyTableVar table(
Name varchar(50),
Identifier uniqueidentifier
;
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
OUTPUT INSERTED.Name, INSERTED.Identifier
INTO #MyTableVar
SELECt Name,Identifier from #MyTableVar
Refreance:
Best way to get identity of inserted row?
SCOPE_IDENTITY() is used to get the last generated Identity value in an identity column in your scope , For GUID values either you get the guid before you insert it like I have done in the code below , or you use OUTPUT clause to get the guid generated by the Insert statement.
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
Declare #NewID UNIQUEIDENTIFIER = NEWID();
insert into NameIdentifier ( Name, Identifier)
values( #name, #NewID);
SELECT * FROM NameAge where Id = #NewID;
END
This should give you your desired functionality.
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
#Ret int Output
AS
BEGIN
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
END
SET #Ret = ##IDENTITY
EDIT: This will return the id of your newly inserted row.
You can achieve this by using the output clause of SQL Server, you can read more about this here
if exists (select 1 from sys.tables where name = 'NameIdentifier ')
drop table NameIdentifier
create table NameIdentifier
(
id BIGINT IDENTITY(1,1)
,Name VARCHAR(100)
,Identifier uniqueidentifier
)
DECLARE #id TABLE
(
ID BIGINT
)
INSERT INTO NameIdentifier (Name,Identifier)
OUTPUT INSERTED.id INTO #id
VALUES('abcd',NEWID())
SELECT * FROM NameIdentifier N, #id I where N.id = I.id

'An explicit value for the identity column can only be specified...' during Merge

There are quite a few questions which cover this error, but I'm having the issue that:
A) I'm currently doing a Merge (with an Insert)
B) I'm not explicitly setting the identity column!
My stored procedure (table names and properties obfuscated):
Table Definition
CREATE TABLE MyTable (
[ID] BIGINT IDENTITY(1, 1) NOT NULL,
[Value] NVARCHAR (256) NOT NULL,
[Property] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [IX_MyTable] UNIQUE NONCLUSTERED ([Value] ASC)
);
Stored Procedure Definition
CREATE TYPE TempType as Table (
[TempValue] nvarchar(256) NOT NULL,
[TempProperty] nvarchar(256) NOT NULL,
);
GO
CREATE PROCEDURE [Name]
#Source TempType READONLY
AS
BEGIN
MERGE [MyTable] as target
USING (SELECT * FROM #Source) as source (TempValue, TempProperty)
ON (target.Value = source.TempValue)
WHEN MATCH THEN
UPDATE SET Value = source.TempValue, Property = source.TempProperty
WHEN NOT MATCHED THEN
INSERT ([Value], [Property])
VALUES (source.TempValue, source.TempProperty)
OUTPUT deleted.*, $action, inserted.* INTO [MyTable];
END
From what I can see, I'm not anywhere explicitly specifying the IDENTITY column. I am specifying a UNIQUE-ly constrained column though.
Lastly, contrary to what the error says, specifying IDENTITY_INSERT ON does nothing.
Edit: I should also specify, I'm getting this error while deploying from a .dacpac via C#.
I would simply get rid of the MERGE statement (has lots of issues by design) and use a simple insert statement as follows:
CREATE PROCEDURE [Name]
#Source TempType READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [MyTable] ([Value], [Property])
SELECT s.TempValue, s.TempProperty
FROM #Source s
WHERE EXISTS (SELECT 1
FROM [MyTable]
WHERE Value = s.TempValue)
END
To read about issues with MERGE statement have a look at this article Use Caution with SQL Server's MERGE Statement
Since you have added an update into your Merge statement, now I would also add an update statement and wrap the update and insert into one transaction but still I would not recommend using merge statement.
CREATE PROCEDURE [Name]
#Source TempType READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
UPDATE T
SET T.[Property] = S.[Property]
FROM [MyTable] T
INNER JOIN #Source s ON T.Value = s.TempValue
INSERT INTO [MyTable] ([Value], [Property])
SELECT s.TempValue, s.TempProperty
FROM #Source s
WHERE NOT EXISTS (SELECT 1
FROM [MyTable]
WHERE Value = s.TempValue)
COMMIT TRANSACTION;
END

Select only few columns from procedure and insert into table

I have a stored procedure that returns 6 columns. But I want to take only 2 columns and insert them into my table variable.
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable EXEC [GetAllTenantCategories] #TenantId
When I run this
Column name or number of supplied values does not match table
definition
How to insert only specified columns from a stored procedure?
I do not want to use SELECT INTO as it is not supported by SQL Azure
Tried below and got Invalid object name '#Temp'
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #Temp EXEC [GetAllTenantCategories] 1
INSERT INTO #CategoryTable (CategoryId, Name)
SELECT CategoryId, Name from #Temp
DROP TABLE #Temp
You can create a temp table first and the INSERT the required columns in your table variable.
CREATE TABLE #temp
(
your columns and datatype
)
INSERT INTO #temp
EXEC [GetAllTenantCategories] #TenantId
Then you can,
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable (CategoryId, Name)
select CategoryId, Name from #temp
Also drop the #temp table,
DROP TABLE #temp
Refer the points taken from https://www.simple-talk.com/sql/performance/execution-plan-basics/
When the Estimated Plan is Invalid
In some instances, the estimated plan won't work at all. For example, try generating an estimated plan for this simple bit of code:
CREATE TABLE TempTable
(
Id INT IDENTITY (1 , 1 )
,Dsc NVARCHAR (50 )
);
INSERT INTO TempTable ( Dsc )
SELECT [Name]
FROM [Sales] .[Store] ;
SELECT *
FROM TempTable ;
DROP TABLE TempTable ;
You will get this error:
Invalid object name 'TempTable'.
The optimizer, which is what is used to generate Estimated Execution plans, doesn't execute T-SQL.
It does run the stateĀ­ments through the algebrizer , the process outlined earlier that is responsible for verifying the names of database objects. Since the query has not yet been executed, the temporary table does not yet exist. This is the cause of the error.
Running this same bit of code through the Actual execution plan will work perfectly fine.
Hope you got why your temp table approach not worked :) Because you might tried as T-SQL
We can use OPENQUERY
SELECT EmployeeID,CurrentSalary INTO #tempEmp
FROM OPENQUERY(LOCALSERVER,'Exec TestDB.dbo.spEmployee')

Get SQL Insert to work when PK is supplied or NOT

I have the following stored procedure:
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
-- If #ServerEnvironmentId was not supplied.
IF (#ServerEnvironmentId IS NULL)
BEGIN
-- Get the ServerEnvironmentId.
SELECT #ServerEnvironmentId = ServerEnvironmentId
FROM #APPL_ServerEnvironment
END
The ServerEnvironmentId column is a primary key with a default set on it, which is (newsequentialid()).
I need this stored procedure to work for 2 scenarios:
Value supplied for ServerEnvironmentId - WORKS.
Value not supplied for ServerEnvironmentId - DOES NOT WORK - CANNOT INSERT NULL VALUE. I thought by setting a default on this column this would be fine.
Someone please help to ammend this procedure so that it may work for both scenarios. Solution needs to have minimal changes as all sp's currently following this trend.
Default values are only applied on inserts if the column is not included in the INSERT list. I'd recommend the following not entirely trivial change (I've commented out the lines to be removed):
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
---- Stores the ServerEnvironmentId.
--DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
IF #ServerEnvironmentName is null
SET #ServerEnvironmentName = newid()
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
--OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
---- If #ServerEnvironmentId was not supplied.
--IF (#ServerEnvironmentId IS NULL)
--BEGIN
-- -- Get the ServerEnvironmentId.
-- SELECT #ServerEnvironmentId = ServerEnvironmentId
-- FROM #APPL_ServerEnvironment
--END
The default constraint will not be used by this procedure, but you can leave it in place if there are other places where rows may be added to the table.
(My first answer was long and so it this one, so I'm posting a second answer.)
I missed that you were using NewSequentialId. Again, if a column is specified within the insert statement, any DEFAULT values assigned to that column will not be used [unless you use the DEFAULT keyword in the INSERT statement, but that's still all or nothing--you can't say "if #Var is null then DEFAULT"]. I think you are stuck with simple branching and semi-redundant code, along the lines of:
ALTER Procedure dbo.APPL_ServerEnvironmentInsert
(
#ServerEnvironmentName varchar(50),
#ServerEnvironmentDescription varchar(1000),
#UserCreatedId uniqueidentifier,
#ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE #APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
IF #ServerEnvironmentId is null
BEGIN
-- ServerEnvironmentId not provided by user, generate during the insert
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId
)
-- Get the new ServerEnvironmentId
SELECT #ServerEnvironmentId = ServerEnvironmentId
FROM #APPL_ServerEnvironment
END
ELSE
BEGIN
-- ServerEnvironmentId is provided by user
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId,
ServerEnvironmentId
)
OUTPUT Inserted.ServerEnvironmentId INTO #APPL_ServerEnvironment
VALUES
(
#ServerEnvironmentName,
#ServerEnvironmentDescription,
GETDATE(),
#UserCreatedId,
#ServerEnvironmentId
)
END
(Why lock the entire table during the insert?)
Help to Simplify SQL Insert which uses NEWSEQUNETIALID() column default