How to insert into a table with a unique identity INT column as primary key - sql

To insert into a table with the next integer ID value, would it look something like this?
DECLARE #RoomID INT
SELECT #RoomID = (SELECT count(*) FROM [dbo].[Rooms])
SELECT #RoomID = SELECT #RoomID + 1
INSERT INTO [dbo].[Rooms]
([RoomID],
[RoomType],
[Description],
[DateCreated],
[IsActive])
VALUES
(#RoomID,
2,
N'Room Description X',
CONVERT(DateTime2, getdate()),
1)

If you want to force a specific number into a column that is an identity column you have to use the command SET IDENTITY_INSERT table_name OFF and turn it back on after your done.
https://learn.microsoft.com/en-us/sql/t-sql/statements/set-identity-insert-transact-sql
If you just want to insert data into the table, you skip the column and SQL Server will insert it for you.
INSERT INTO [dbo].[Rooms]
(
[RoomType],
[Description],
[DateCreated],
[IsActive])
VALUES
(
2,
N'Room Description X',
CONVERT(DateTime2, getdate()),
1)

Related

SQL Insert values by join

Perhaps it's too late and that's why I am stuck. I want to fill a database with values but only for those values where a date already exists in the data base. The structure is the following:
CREATE TABLE dbo.TEST(ID INT IDENTITY(1,1) NOT NULL,date_time datetime)
ALTER TABLE dbo.TEST ADD "column1" FLOAT;
INSERT INTO dbo.TEST(date_time,"column1")
VALUES ('2018-04-01 02:00:00',1),('2018-04-01 06:00:00',2),('2018-04-01 07:00:00',3)
ALTER TABLE dbo.TEST ADD "column2" FLOAT;
so the table looks like this:
now I want to fill column2 for 2:00 and 6:00 o clock with the values 20 and 21 but ignore value 25. What I have is
INSERT INTO dbo.TEST("column2")
SELECT
NewValues."column2"
FROM (
VALUES ('2018-04-01 02:00:00',20),
('2018-04-01 06:00:00',21),
('2019-10-05 20:30:00',25)
) AS NewValues(date_time,"column2")
INNER JOIN dbo.TEST
ON dbo.TEST.date_time = NewValues.date_time
WHERE dbo.TEST.date_time = NewValues.date_time
but this results in
what am I missing?
You want an update:
update t
set column2 = NewValues.column2
from dbo.TEST t left join
(values ('2018-04-01 02:00:00', 20),
('2018-04-01 06:00:00', 21),
('2019-10-05 20:30:00', 25)
) NewValues(date_time, column2)
ON t.date_time = NewValues.date_time;

SQL Server : procedure tables cannot insert value null

I want to add 100 storages in a table.
This is my procedure:
CREATE PROCEDURE [add100*sTORAGE]
AS
DECLARE #i int, #start DATETIME, #end DATETIME
SET #start = GETDATE()
SET #i = 1
WHILE #i < 101
BEGIN
INSERT INTO Storage(storage_name)
VALUES (CONCAT('Nume', CONVERT(nvarchar, #i)))
SET #i = #i +1
END
SET #end = GETDATE()
DECLARE #testID INT = (SELECT TOP 1 (TestRunID)
FROM TestRuns
ORDER BY TestRunID DESC)
DECLARE #tableID INT = (SELECT tableID
FROM Tables
WHERE Name = 'Storage')
INSERT INTO TestRunTables (TestRunID, TableID, StartAt, EndAt)
VALUES (#testID, #tableID, #start, #end)
GO
I get an error after its execution:
Msg 515, Level 16, State 2, Procedure add100*sTORAGE, Line 13
Cannot insert the value NULL into column 'TestRunID', table 'OnlineShop.dbo.TestRunTables'; column does not allow nulls. INSERT fails.
When I look in the table, it has been created 99 columns.
I have some empty tables in a relation and this are the inserts of it (maybe here is the cause):
--INSERTS--
-- insert views into "Views"
INSERT INTO Views(Name) VALUES ('View1')
INSERT INTO Views(Name) VALUES ('View2')
INSERT INTO Views(Name) VALUES ('View3')
select * from views
delete from views where ViewID>1
-- insert into "Tests"
INSERT INTO Tests(Name) VALUES ('[add100*Storage-runView1-del100*Storage]')
INSERT INTO Tests(Name) VALUES ('[add100*Product-runView2-del100*Product]')
INSERT INTO Tests(Name) VALUES ('[add100*OrderProduct-runView3- del100*OrderProduct]')
SELECT * FROM Tests
--insert into tables
INSERT INTO Tables(Name) VALUES ('Table1')
INSERT INTO Tables(Name) VALUES ('Table2')
INSERT INTO Tables(Name) VALUES ('Table3')
SELECT * from Tables
-- insert into "testTable"
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (1,1,100,1)
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (3,2,100,1)
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (2,3,100,1)
SELECT * FROM TestTables
-- insert into "testViews"
INSERT INTO TestViews(TestID,ViewID) VALUES (1,1)
INSERT INTO TestViews(TestID,ViewID) VALUES (3,2)
INSERT INTO TestViews(TestID,ViewID) VALUES (2,3)
SELECT * FROM TestViews
What's wrong? Thank you.
The error tells you everything--table TestRunTables has column "TestRunID" which requires that field to have a value. You either need to be sure to insert a value into that field, or alter the column so that it will use a default value when you don't specify it.
This line:
DECLARE #testID INT = (SELECT TOP 1 (TestRunID) FROM TestRuns ORDER BY TestRunID DESC)
will set #testID to null if no records are returned from TestRuns or if the first TestRunID is null. This is probably what you need to fix.

Can a Pivot table be used with a unknown number of columns?

If I have a team table with a unknown amount of members, is there a way to make the pivot query dynamic?
create table #t (
team varchar (20), member varchar (20)
)
insert into #t values ('ERP', 'Jack')
insert into #t values ('ERP', 'John')
insert into #t values ('ERP', 'Mary')
insert into #t values ('ERP', 'Tim')
insert into #t values ('CRM', 'Robert')
insert into #t values ('CRM', 'Diana')
select * from #t
select team, [1] as teamMember1, /* 1st select */
[2] as teamMember2, [3] as teamMember3
from
(select team , member, row_number () /* 3rd select */
over (partition by team order by team) as rownum
from #t) a
pivot (max(member) for rownum in ([1], [2], [3])) as pvt
drop table #t
Why yes, yes there is. Here's a script I cooked up years ago for a similar problem that was ultimately solved by giving the user Excel and washing my hands of it. I apologize it's not configured with your example data, but hopefully it's easy to follow.
Hope that helps,
John
--------------START QUERY--------------
-- Example Table
CREATE TABLE #glbTestTable
(
ProviderID INT,
Total INT,
PaymentDate SMALLDATETIME
)
--So the dates insert properly
SET DATEFORMAT dmy
-- Populate Example Table
INSERT INTO #glbTestTable VALUES (232, 12200, '12/01/09')
INSERT INTO #glbTestTable VALUES (456, 10200, '12/01/09')
INSERT INTO #glbTestTable VALUES (563, 11899, '02/03/09')
INSERT INTO #glbTestTable VALUES (221, 5239, '13/04/09')
INSERT INTO #glbTestTable VALUES (987, 7899, '02/03/09')
INSERT INTO #glbTestTable VALUES (1, 1234, '02/08/09')
INSERT INTO #glbTestTable VALUES (2, 4321, '02/07/09')
INSERT INTO #glbTestTable VALUES (3, 5555, '02/06/09')
-- Raw Output
SELECT *
FROM #glbTestTable
-- Build Query for Pivot --
DECLARE #pvtColumns VARCHAR(MAX)
SET #pvtColumns = ''
-- Grab up to the first 1023 "Columns" that we want to use in Pivot Table.
-- Tables can only have 1024 columns at a maximum
SELECT TOP 1023 #pvtColumns = #pvtColumns + '[' + CONVERT(VARCHAR, PaymentDate, 103) + '], '
FROM (SELECT DISTINCT PaymentDate FROM #glbTestTable) t_distFP
-- Create PivotTable Query
DECLARE #myQuery VARCHAR(MAX)
SET #myQuery = '
SELECT ProviderID, ' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + '
FROM (SELECT ProviderID, PaymentDate, Total
FROM #glbTestTable) AS SourceTable
PIVOT
(
SUM(Total)
FOR PaymentDate IN (' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + ')
) AS PivotTable'
-- Run the Pivot Query
EXEC(#myQuery)
-- Cleanup
DROP TABLE #glbTestTable
---------------END QUERY---------------

Splitting one row into more rows -- table transformation

I have one source table that should be converted to one destination table. The source table contains four columns with sensor values. The destination table should contain four rows with the single sensor value and with one column for number of the sensor -- for each row from the source table. In other words, the destination table will have four times more rows. (I believe this is called normalization. At least, I think it will be more practical in future when more or less or different sensors are to be used.)
More background information to explain. I have already successfully tried an insert trigger that does that for a single line:
CREATE TRIGGER dbo.temperatures_to_sensors
ON dbo.Data
AFTER INSERT
AS
BEGIN
DECLARE #line_no TINYINT;
SET #line_no = 2; -- hardwired for the production line
DECLARE #UTC DATETIME;
DECLARE #value1 FLOAT;
DECLARE #value2 FLOAT;
DECLARE #value3 FLOAT;
DECLARE #value4 FLOAT;
SELECT
#UTC = CAST((CAST(LEFT(inserted.UTC, 16) AS FLOAT) - 2415020.5) AS DATETIME),
#value1 = inserted.temperature_1,
#value2 = inserted.temperature_2,
#value3 = inserted.temperature_3,
#value4 = inserted.temperature_4
FROM inserted;
INSERT INTO dbo.line_sensor_values
(UTC, line_no, sensor_no, sensor_value)
VALUES (#UTC, #line_no, 1, #value1),
(#UTC, #line_no, 2, #value2),
(#UTC, #line_no, 3, #value3),
(#UTC, #line_no, 4, #value4);
END;
GO
Now, I would like to initialize the destination table from the old table once. After that, the trigger will continue to fill the values.
I am not good in SQL. I tried:
CREATE PROCEDURE dbo.init_line_sensor_values
AS
BEGIN
DECLARE #line_no TINYINT;
SET #line_no = 2; -- hardwired for the production line
DECLARE #UTC DATETIME;
DECLARE #value1 FLOAT;
DECLARE #value2 FLOAT;
DECLARE #value3 FLOAT;
DECLARE #value4 FLOAT;
INSERT INTO dbo.line_sensor_values
(UTC, line_no, sensor_no, sensor_value)
VALUES (#UTC, #line_no, 1, #value1),
(#UTC, #line_no, 2, #value2),
(#UTC, #line_no, 3, #value3),
(#UTC, #line_no, 4, #value4)
SELECT
#UTC = CAST((CAST(LEFT(t.UTC, 16) AS FLOAT) - 2415020.5) AS DATETIME),
#value1 = t.temperature_1,
#value2 = t.temperature_2,
#value3 = t.temperature_3,
#value4 = t.temperature_4
FROM dbo.Data AS t;
END;
GO
EXECUTE dbo.init_line_sensor_values
GO
... but it fails with
Cannot insert the value NULL into column 'UTC', table '1000574.dbo.line_sensor_values'; column does not allow nulls. INSERT fails.
It is apparent that the SELECT should be used differently to feed the INSERT. Or do I have to use the loop? (Cursor created and FETCH NEXT... and WHILE...)
UPDATED
The source table can be created this way (simplified):
CREATE TABLE dbo.Data(
UTC varchar(32) NOT NULL,
temperature_1 float NULL,
temperature_2 float NULL,
temperature_3 float NULL,
temperature_4 float NULL
PRIMARY KEY CLUSTERED
(
UTC ASC
)
GO
The destination table was created this way:
CREATE TABLE dbo.line_sensor_values (
UTC DATETIME NOT NULL,
line_no TINYINT NOT NULL, -- line number: 1, 2, 3, etc.
sensor_no TINYINT NOT NULL, -- sensor number: 1, 2, 3, etc.
sensor_value float NULL, -- the measured value
PRIMARY KEY CLUSTERED (
UTC ASC,
line_no ASC,
sensor_no ASC
)
)
GO
Thanks for your help, Petr
If all you need to do is to convert a table with four columns into a single table where each row represents a row number from a source table and a column from a source table, then here is an example:
Here is SQLFiddle
create table fourColumns
(
column1 varchar(50),
column2 varchar(50),
column3 varchar(50),
column4 varchar(50)
)
insert into fourColumns select 'A','B','C','D'
insert into fourColumns select 'E','F','G','H'
;with MyCTE (lineNumber, columnNumber, Result)
as
(
select ROW_NUMBER() OVER(ORDER BY column1 ASC) AS Row, 1, column1
from fourColumns
union all
select ROW_NUMBER() OVER(ORDER BY column2 ASC) AS Row, 2, column2
from fourColumns
union all
select ROW_NUMBER() OVER(ORDER BY column3 ASC) AS Row, 3, column3
from fourColumns
union all
select ROW_NUMBER() OVER(ORDER BY column4 ASC) AS Row, 4, column4
from fourColumns
)
-- add insert here
select lineNumber,
columnNumber,
Result
from MyCTE
order by lineNumber
INSERT INTO dbo.line_sensor_value
(UTC, line_no, sensor_no, sensor_value)
select UTC, line_no, sensor_no, temperature_1 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_2 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_3 as sensor_value from dbo.Data
union
select UTC, line_no, sensor_no, temperature_4 as sensor_value from dbo.Data

display all column with one column masked

I have two columns - name and ccNumber. I want to display both the column with one of them masked.
This query is showing only one column but I want all column to be displayed:
declare #t table (card_no varchar(20))
insert into #t
select ccNUMBER from ccinfo
select 'XXXX-XXXX-XXXX-'+ substring(card_no, 13, 4) as card_no from #t
i want name column with ccnumber column to be masked
You can try below
declare #t table (name varchar(100),card_no varchar(20))
insert into #t
select name, ccNUMBER from ccinfo
select name, 'XXXX-XXXX-XXXX-'+ substring(card_no, 13, 4) as card_no from #t
check the following example. i think you need concatenation of columns.
create table demo
(
firstName varchar(30),
secondName varchar(30)
);
insert into demo
values
('soumyajit', 'chatterjee'),
('papai', 'chatterjee'),
('virat', 'kohli');
select concat(firstName, ' ', secondName)as Name from demo;
You need to get the second column, too:
declare #t table (card_no varchar(20), name varchar(64));
insert into #t
select ccNUMBER, name from ccinfo
select 'XXXX-XXXX-XXXX-'+ substring(card_no, 13, 4) as card_no, name from #t
or just use the original table:
select 'XXXX-XXXX-XXXX-'+ substring(ccNUMBER, 13, 4) as card_no, name from ccinfo