I have temp table each time store 100 values based on a specific condition.
I need Slno as 1,2,3,4 ...100 each time query executes .
If I use below syntax's, the 'Slno' is taking some other numbers
create table #temptable
(Slno INT IDENTITY(1,1) NOT NULL ,
Name varchar(50)
)
create table #temptable
(Slno int IDENTITY(1,1) PRIMARY KEY ,
Name varchar(50)
)
Please help if there is a way out without using Rank()?
You need to create an IDENTITY column as follows:
Syntax:
CREATE TABLE (
ID_column INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
...
);
It should be
Identity(seed,increment)
Here you go:
CREATE TABLE #temptable
(Slno INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
Name varchar(50)
)
Example:
INSERT INTO #temptable (Name) Values ('ABC')
INSERT INTO #temptable (Name) Values ('ABhshC')
INSERT INTO #temptable (Name) Values ('ABQRAC')
INSERT INTO #temptable (Name) Values ('ABhsAERAYRHAERhC')
SELECT * FROM #temptable
Results:
Slno Name
1 ABC
2 ABhshC
3 ABQRAC
4 ABhsAERAYRHAERhC
Related
I have an existing table, A, defined as follows:
CREATE TABLE dbo.A(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
name nvarchar(255) NOT NULL UNIQUE NONCLUSTERED
);
This table has 1,000s of existing records.
I now require a new table, B, defined as follows:
CREATE TABLE dbo.B(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
some_value int NOT NULL
);
I need to create a record in B for each record in A and add a reference from the A record to the corresponding B record. Firstly, I need to add a new field to table A that references table B (which necessarily must be nullable with a default value of NULL, at this stage):
ALTER TABLE dbo.A
ADD b_id int NULL references dbo.B;
How can I create the necessary B records and update the A.b_id field accordingly? I'm looking for something like this:
UPDATE dbo.A
SET b_id = (INSERT INTO dbo.B(some_value) VALUES(5));
such that the value of b_id is the id field of the newly inserted B. (Clearly, this query isn't valid.)
The only solution I can come up with is to write a complex stored procedure using multiple, separate queries. Is there a way to do this with a single query?
IF I am understanding correctly, there's no need for a CURSOR here. What you could do is a MERGE that allows your to OUTPUT both columns from the source data and the target:
CREATE TABLE dbo.A(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
name nvarchar(255) NOT NULL UNIQUE NONCLUSTERED
);
GO
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N))
INSERT INTO dbo.A
SELECT NEWID()
FROM N N1, N N2, N N3;
GO
CREATE TABLE dbo.B(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
some_value int NOT NULL
);
GO
ALTER TABLE dbo.A
ADD b_id int NULL references dbo.B;
GO
DECLARE #IDs table (a_id int, b_id int)
MERGE dbo.B B
USING dbo.A A ON B.id = A.b_id
WHEN NOT MATCHED BY TARGET THEN
INSERT (some_value)
VALUES(RAND() * 1000)
OUTPUT A.id, inserted.id
INTO #IDs;
UPDATE A
SET b_id = I.b_id
FROM dbo.A A
JOIN #Ids I ON A.id = I.a_id;
GO
SELECT *
FROM dbo.A;
GO
DROP TABLE dbo.A;
DROP TABLE dbo.B;
db<>fiddle
If you are willing (and able) to make a slight adjustment to TableB as well, you can use OUTPUT when inserting. I added a_id to TableB for my example. Updating b_id back to TableA is a bit redundant as you would now have TableA's ID in TableB for joining.
Here's an example.
-- Mock tables.
DECLARE #TableA table ( id int IDENTITY (100,1) PRIMARY KEY, [name] nvarchar(255), b_id int );
DECLARE #TableB table ( id int IDENTITY (1,1) PRIMARY KEY, a_id int, some_value int );
-- Mock data.
INSERT INTO #TableA ( [name] ) VALUES
( 'TableA_1' ), ( 'TableA_2' ), ( 'TableA_3' );
-- Create an OUTPUT table to capture the values inserted into TableB.
DECLARE #out table ( a_id int, b_id int );
INSERT INTO #TableB ( a_id, some_value )
OUTPUT inserted.a_id, inserted.id INTO #out
SELECT
id AS a_id, 999 AS some_value
FROM #TableA;
-- Update TableA's b_id column.
UPDATE #TableA
SET
b_id = o.b_id
FROM #TableA AS a
INNER JOIN #out AS o
ON a.id = o.a_id;
-- Show updated results.
SELECT * FROM #TableA ORDER BY id;
Returns
+-----+----------+------+
| id | name | b_id |
+-----+----------+------+
| 100 | TableA_1 | 1 |
| 101 | TableA_2 | 2 |
| 102 | TableA_3 | 3 |
+-----+----------+------+
I created a table type:
CREATE TYPE int_array AS TABLE (n INT NOT NULL)
and want to use it to insert several rows in a single procedure into the following table:
CREATE TABLE myTable
(
Id_SecondTable INT NOT NULL,
Id_ThirdTable INT NOT NULL,
CONSTRAINT PK_myTable
PRIMARY KEY (Id_SecondTable, Id_ThirdTable),
CONSTRAINT FK_Id_SecondTable
FOREIGN KEY (Id_SecondTable) REFERENCES SecondTable (Id),
CONSTRAINT FK_Id_ThirdTable
FOREIGN KEY (Id_ThirdTable) REFERENCES ThirdTable (Id)
)
My procedure is as follows:
CREATE PROCEDURE test
(#value INT,
#array int_array READONLY)
AS
BEGIN
INSERT INTO myTable
VALUES (Id_SecondTable, Id_ThirdTable) (#value, SELECT n FROM #array)
END
What am I doing wrong?
You can't mix a scalar value and select statement in your insert. You need to make the scalar value a column in the select instead. Like this.
CREATE PROCEDURE test(
#value INT,
#array int_array readonly
)
AS
BEGIN
INSERT INTO myTable
(
Id_SecondTable
, Id_ThirdTable
)
SELECT #value
, n
FROM #array
END
Why does SCOPE_IDENTITY() return NULL after inserting a row in the ComponentAssociation table (as ##IDENTITY returns the right Id)
while SCOPE_IDENTITY() returns the right Id after inserting a row in the CustomerProjectAssociation table ?
The two association tables are created the same way.
Here is an extract of the table creation script:
-- Creating table 'CustomerProjectAssociation'
CREATE TABLE [dbo].[CustomerProjectAssociation]
(
[Id] int IDENTITY(1,1) NOT NULL,
[CustomerId] int NOT NULL,
[ProjectId] int NOT NULL,
[CreationDate] datetime NOT NULL CONSTRAINT DF_CustomerProjectAssociation_CreationDate DEFAULT (SYSUTCDATETIME()),
[LastModificationDate] datetime NOT NULL CONSTRAINT DF_CustomerProjectAssociation_ModificationDate DEFAULT (SYSUTCDATETIME())
);
GO
-- Creating table 'ComponentAssociation'
CREATE TABLE [dbo].[ComponentAssociation]
(
[Id] int IDENTITY(1,1) NOT NULL,
[EcuId] int NOT NULL,
[CreationDate] datetime NOT NULL CONSTRAINT DF_ComponentAssociation_CreationDate DEFAULT (SYSUTCDATETIME()),
[LastModificationDate] datetime NOT NULL CONSTRAINT DF_ComponentAssociation_ModificationDate DEFAULT (SYSUTCDATETIME()),
[ComponentId] int NOT NULL
);
GO
-- Creating primary key on [Id] in table 'CustomerProjectAssociation'
ALTER TABLE [dbo].[CustomerProjectAssociation]
ADD CONSTRAINT [PK_CustomerProjectAssociation]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
-- Creating primary key on [Id] in table 'ComponentAssociation'
ALTER TABLE [dbo].[ComponentAssociation]
ADD CONSTRAINT [PK_ComponentAssociation]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
And here are two queries executed on the database from SQL Server Management Studio:
INSERT [dbo].[CustomerProjectAssociation]([CustomerId], [ProjectId])
VALUES (1, 2)
SELECT
[RowCount] = ##RowCount,
[##IDENTITY] = ##IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
Result:
RowCount ##IDENTITY SCOPE_IDENTITY
1 24 24
INSERT [dbo].[ComponentAssociation]([EcuId], [ComponentId])
VALUES(1, 2)
SELECT
[RowCount] = ##RowCount,
[##IDENTITY] = ##IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
Result:
RowCount ##IDENTITY SCOPE_IDENTITY
1 613 NULL
OK, the issue is solved.
Found the solution here: error when inserting into table having instead of trigger from entity data framework
I added the following select statement at the end of the instead of insert,update trigger returning all the computed columns:
select [Id], [CreationDate], [LastModificationDate] from {0}.[dbo].[ComponentAssociation] where ##ROWCOUNT > 0 and Id = scope_identity()
I'm trying to create a trigger after an insert on the eventss table. The trigger should select the Bcoordinator_ID from the bookingCoordinator table where they have the minimum number of occurrences in the eventss table.
Here's my table data followed by the trigger. It doesn't like the minCount in the values, I think it's looking for and int.
DROP TABLE eventsBooking
CREATE TABLE eventsBooking
(
EBK INT NOT NULL IDENTITY(100, 1),
booking_ID AS 'EBK'+CAST( ebk as varchar(10)) PERSISTED PRIMARY KEY,
bookingDate DATE,
Bcoordinator_ID VARCHAR (20),
eventss_ID VARCHAR (20) NOT NULL
)
INSERT INTO eventsBooking
VALUES ('2015-01-07 11:23:00', NULL, 'EVT100');
Eventss table:
EVT INT NOT NULL IDENTITY(100, 1),
eventss_ID AS 'EVT' + CAST(evt as varchar(10)) PERSISTED PRIMARY KEY,
eventsName varchar(50),
noOfStages SMALLINT,
noOfRounds SMALLINT,
eventsDate DATE,
entryFee DECIMAL (7,2),
venue_ID VARCHAR (20) NOT NULL,
judges_ID VARCHAR (20)
INSERT INTO eventss
VALUES ('Swimming Gala 2015', '3', '7', '2015-01-07 09:00:00', '35.00', 'VEN101', 'JUD100');
CREATE TABLE bookingCoordinator
(
BCO INT NOT NULL IDENTITY(100, 1),
Bcoordinator_ID AS 'BCO'+CAST( bco as varchar(10)) PERSISTED PRIMARY KEY,
forename varchar(20) NOT NULL,
familyName varchar(50)
)
INSERT INTO bookingCoordinator VALUES ('Steve', 'Wills');
Trigger:
CREATE TRIGGER TRGinsertJudge
ON [dbo].[eventss]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.eventsBooking (Bcoordinator_ID, bookingDate, Eventss_ID)
VALUES(minCount, getdate(), 100)
SELECT MIN(COUNT(Bcoordinator_ID)) AS minCount
FROM eventsBooking
END
You can't do an aggregation of an aggregation i.e. MIN(COUNT(1))
If you just want the Bcoordinatior_ID with the least counts in eventsBooking, do this
select top 1 bcoordinator_id
from eventsBooking
group by bcoordinator_id
order by count(1) asc
And you don't use VALUES() in an INSERT INTO ... SELECT statement
Also, in your current code, since eventsBooking.bcoordinator_id is always null, you need to join to the actual table of bookingCoordinators to return booking coordinators without any events booked.
So your complete trigger statement should be
INSERT INTO dbo.eventsBooking (Bcoordinator_ID, bookingDate, Eventss_ID)
select
top 1
bookingcoordinator.bcoordinator_id, getdate(), 100
from bookingCoordinator left join eventsBooking
on bookingCoordinator.Bcoordinator_ID = eventsBooking.Bcoordinator_ID
group by bookingcoordinator.bcoordinator_id
order by count(1) asc
How to declare one element table so it can be used in future queries?
DECLARE #Emp TABLE
(
ID BIGINT NULL,
CompanyID BIGINT NULL
)
INSERT INTO #EMP
SELECT ID,CompanyID FROM Emp WHERE PIN = 123
SELECT COMPANYID FROM COMPANY WHERE ID = #Emp.CompanyID
You can not. A table per definition contains a (possibly) unlimited number of elements. However, you can always do something like this:
DECLARE #CompanyID BIGINT
SET #CompanyID = (SELECT TOP 1 CompanyID FROM #Emp WHERE ...)
By the way, the following line is not correct, as the WHERE clause is incomplete.
SELECT COMPANYID FROM COMPANY WHERE #Emp.CompanyID
If you intention is to create a table variable that will only store a maximum of one row, you can do it like this:
DECLARE #Emp TABLE
(
ID BIGINT NULL,
CompanyID BIGINT NULL,
Lock char(1) not null default 'X' primary key check(Lock='X')
)
INSERT INTO #EMP (ID,CompanyID)
SELECT ID,CompanyID FROM Emp WHERE PIN = 123
Because the table's primary key is constrained to only one possible value, logically there can't be more than one row.