SQL if #name exists select ID else insert #name into table - sql

Table looks like below:
CREATE TABLE names
(ID int,
name varchar(10) unique)
I need to achieve the following result:
if #name not exists in names then insert into names (name) values (#name)
select id from names where name=#name
It would be best to achieve it with user defined function.

You basically have the answer written in your question already:
IF (NOT EXISTS (SELECT * FROM names WHERE name = #name))
INSERT INTO names (name) values (#name);
SELECT id FROM names WHERE name = #name;
The only problem is that you haven't set up your table names to use an IDENTITY column. This means you need to assign values for id as well.

Related

SQL Inserted table trigger

If I run the following select statement inside an insert trigger, is it possible that it will return more than one result?:
DECLARE #variable char(1) = (SELECT ID FROM inserted)
If so, then what's the best to handle it?
Here is the problem that I am trying to solve: Every time when the new record is inserted into a table, I want to take the newly inserted ID and insert it into another table(if it doesn't exists).
Thank you!
Instead of
DECLARE #variable char(1) = (SELECT ID FROM inserted)
You can do something like following:
Declare #VarTempTbl as table (id int)
Insert into #VarTempTbl (id)
Select id from inserted
So that you can get those values for further processing
Now, I had created Two tables One for Master table and another for When any Insertion happens in that Master table, that entry has to inserted into the another table.
CREATE TABLE tblEmployee
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
CREATE TABLE tblEmployee_New
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
Trigger:
CREATE TRIGGER TR_EMPLOYEEDETAILS_AFTEROFINSERT
ON TBLEMPLOYEE
AFTER INSERT
AS
BEGIN
TRUNCATE TABLE tblEmployee_New
INSERT INTO TBLEMPLOYEE_NEW(ID, NAME, GENDER, DEPARTMENTID)
SELECT ID, NAME, GENDER, DEPARTMENTID
FROM INSERTED
END
Now Lets try to insert into record into a master table
Insert into tblEmployee values (1,'John', 'Male', 3)
Insert into tblEmployee values (2,'Mike', 'Male', 2)
It has automatically insert the newly inserted records into the another table.
If your want to remove the Previous records then add a drop Statement in that above Trigger.
Note: You can also use #Temp Table instead of creating a another table('tblEmployee_New')
Kinldy Share your comments

Generate ID for duplicate values in sql server

I found following link to assign identical ID to duplicates in SQL server,
my understanding there is no sql server function to automatically generate it rather than using insert and update queries in link attached, is that statement True, if yes, then what would be the trigger if for example someone insert data to MyTable then run insert and update query from link:
Assign identical ID to duplicates in SQL server
INSERT INTO secondTable (word) SELECT distinct word FROM MyTable;
UPDATE MyTable SET ID = (SELECT id from secondTable where MyTable.word = secondTable.word)
thanks,
S
Is this what you want? I can't think of an "automatic" solution that would just increase the Id for new words.
CREATE TABLE MyTable (
Id INT NOT NULL,
Word NVARCHAR(255) NOT NULL
PRIMARY KEY (Id, Word)); -- primary key will make it impossible to have more than one combination of word and id
DECLARE #word NVARCHAR(255) = 'Hello!';
-- Get existing id or calculate a new id
DECLARE #Id INT = (SELECT Id FROM MyTable WHERE Word = #word);
IF(#id IS NULL) SET #Id = (SELECT MAX(Id) + 1 FROM MyTable);
INSERT INTO MyTable (Id, Word)
VALUES (#id, #word)
SELECT * FROM MyTable
If you can't for some reason have id and word as a combined primary key, you may use an unique index to make sure that there is only one combination

Select from multiple table (passed by another select)

Question updated.
What I want to achive is to get list of new tables which are empty or null in description field. (new tables means with prefix new_) and all tables have description field.
Table definition:
create table topic (id int, description varchar(255));
create table comment (id int, description varchar(255));
create table author (id int, description varchar(255));
create table new_topic (id int, description varchar(255));
create table new_comment (id int, description varchar(255));
create table new_author (id int, description varchar(255));
Sample data and description:
insert into new_topic (id, description) values (1, null);
insert into new_topic (id, description) values (2, 'This is topic description');
insert into new_comment (id, description) values (1, null);
insert into new_comment (id, description) values (2, null);
insert into new_author (id, description) values (1, 'This is casual first author.');
insert into new_author (id, description) values (2, 'This is casual second author.');
Like you can notice on my example ideal output for my sample data would've be:
table_name:
new_topic
new_comment
My actual solution works, but I need to manually add tables and I make a lot of repetitions.
select distinct 'new_topic' as table_name
from new_topic where description is null
select distinct 'new_comment' as table_name
from new_comment where description is null
select distinct 'new_author' as table_name
from new_author where description is null
And output of my solution is like below:
table_name
new_topic
table_name
new_comment
table_name
I also created SELECT to get all new tables:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'new_%' AND TABLE_TYPE = 'BASE TABLE'
Which could've be an entry point for my previous select, but I don't know how to connect those two.
Also my solution is avaiable on dbfiddle
Oh I think I understand what you are after. Yes this requires dynamic sql. Also, please note that your query to find all tables with a name like new_ is not quite right. The underscore is a wildcard pattern check. So that would return a table named "news" when you don't want it to. Wrap the underscore in square brackets to solve this. Here is how I would go about this type of query. The comments in the code should explain this.
declare #SQL nvarchar(max) = '' --this must be initialized to an empty string for this to work.
select #SQL = #SQL + 'select distinct TableName = ''' + t.name + ''' from ' + quotename(t.name) + ' where description is null union all '
from sys.tables t
where name like 'new[_]%' --need the square brackets because the underscore is a wildcard so you might get false positives
select #SQL = left(#SQL, len(#SQL) - 10)
--this will show you the dynamic sql
select #SQL
--once you are satisfied the dynamic sql is correct uncomment the next line to execute it
--exec sp_executesql #SQL
Could you not just do:-
select table_name from information_schema.columns
where table_name like 'prefix_%' and (column_name is null or column_name='')

Dynamically alias columns from a view query SQL

How can I use dynamic SQL to query a table, and then use one of the results to alias a column?
I'm trying something like:
SELECT
ID, ModelName INTO #tmpTable
FROM Models
And then:
SELECT
ModelNumber AS (SELECT ModelName FROM #tmpTable)
FROM NewModels
For those asking for more detail:
We have a view that contains everything we want, but the columns are IDs like "def123". In another table we have the names that resolve the IDs like "def123", "FName". We want to query the view but have the name appear (using AS) instead of the ID. Essentially, we want to query the definitions table in the AS statement to get dynamic naming.
Do not try to bend the dynamic SQL, only realize the truth of it, there is no need for it...
A ModelName by another other ModelNumber will still smell the same ...
#IMissSQLQuotes
select ID
, ModelName as ModelNumber
from NewModels
One possible path to consider would be to replace alias names in a dynamic sql.
Based on a table with the new alias names.
Example snippet:
IF OBJECT_ID('tempdb..#NewModels') IS NOT NULL DROP TABLE #NewModels;
CREATE TABLE #NewModels (ModelNumber int, ModelType char(1));
INSERT INTO #NewModels (ModelNumber, ModelType) values
(100, 'A'),
(101, 'B'),
(102, 'C');
IF OBJECT_ID('tempdb..#tmpModelNames') IS NOT NULL DROP TABLE #tmpModelNames;
CREATE TABLE #tmpModelNames (Code varchar(30) primary key, ModelName varchar(30));
INSERT INTO #tmpModelNames (Code, ModelName) values
('Col1', 'Model Name 1'),
('Col2', 'Model Name 2');
DECLARE #Sql NVARCHAR(max) = 'SELECT
ModelNumber AS [Col1],
ModelType AS [Col2]
FROM #NewModels
WHERE ModelNumber = #ModelNumber';
select #Sql = replace(#Sql, quotename(Code), quotename(ModelName)) from #tmpModelNames;
--select #Sql as Sql;
EXECUTE sp_executesql #Sql, N'#ModelNumber int', #ModelNumber = 101;
Returns:
Model Name 1 Model Name 2
------------ -------------
101 B

Comparing data in the same table for non existent rows

I have a table that has both Company name and Contacts for their respective companies. Type column has a 0 or 1 indicating whether it is a company or person. Each row has a column with a unique contact no. The 'person' row has a column called "Company no." that links the person to the company. I'm trying to return rows that show a company without any contacts in the same table. Not sure how to even start writing this query.
Try it like this:
DECLARE #tbl TABLE(ContactNo INT, Name VARCHAR(100), [Type] INT,CompanyNo INT);
INSERT INTO #tbl VALUES
(100,'ACME, Inc.',0,100)
,(200,'Bob Smith',1,100)
,(300,'John Doe',1,100)
,(400,'Widget World',0,400)
,(500,'Fishing, Inc.',0,500)
,(600,'Jane Doe',1,500);
WITH TheCompanies AS
(
SELECT *
FROM #tbl AS tbl
WHERE tbl.[Type]=0
)
SELECT *
FROM TheCompanies
WHERE NOT EXISTS(SELECT 1 FROM #tbl WHERE [Type]=1 AND CompanyNo=TheCompanies.CompanyNo);