if(OBJECT_ID('EgTb')is not null)drop table [EgTB];
GO
create table [EgTB](Name varchar(50),country varchar(50))
insert into EgTB values('aaa','sg');
insert into EgTB values('bbb','uk');
insert into EgTB values('ccc','us');
insert into EgTB values('ddd','au');
GO
select * from EgTB;
declare #cou varchar(50), #firstCou varchar(50), #secondCou varchar(50);
set #firstCou='sg';
set #secondCou='uk';
if(#cou is null)
begin
set #cou=#firstCou+','+#secondCou;
end
select * from EgTB where (#cou is null or country in (#cou));
GO
if(OBJECT_ID('EgTb')is not null)drop table [EgTB];
GO
The above code is the one I stimulated.
there is a variable #cou.
That variable is the one using in where.
what I want is.. if #cou is null, I want to use #firstCou and #secondCou.
Instead of doing where country in (#firstCou,#secondCou)
I want where country in (#cou) with those 2 variable values in #cou.
cos the real thing is not 2 extra variable.. I will retreieve several records and I won't know the fixed record.
That's why I want to use IN()
But my problem is when I add those 2 values into #cou, the #cou value becomes 'sg,uk' instead of 'sg','uk'.
it is expected but how can i make it so that it becomes 'sg','uk'
You can not replace the parameters for IN with a string literal. In takes a list of expressions or a sub-query as an argument.
You could use a table variable instead with one column and one row for each country.
declare #cou table(country varchar(50))
Insert the countries you look for to the table variable and use a query that looks like this.
select *
from EgTB
where country in (select country from #cou)
Related
I am able to create table, shred JSON and add data if it does not exist in SQL Server:
DECLARE #json nvarchar(max);
SET #json = N'[{"IplayerName": "Pilipiliz",
"Sname": "kikombe",
"WeightLBs":"60.236"
}]'
IF NOT EXISTS (SELECT * FROM sys.objects WHERE OBJECT_ID = object_id('Iplayerds'))
BEGIN
SELECT
[IplayerName],
[Sname],
[WeightLBs]
INTO
Iplayerds
FROM
OPENJSON(#json)
WITH (IplayerName NVARCHAR(200),
Sname NVARCHAR(20),
WeightLBs DECIMAL(10,4)
)
END
ELSE
PRINT 'exists'
However, when I try to replace the print statement with insert rows code shown below, it fails
INSERT INTO Iplayerds (IplayerName, Sname, WeightLBs)
VALUES ([IplayerName], [Sname], [WeightLBs]
FROM OPENJSON(#json))
What am I doing wrong?
The INSERT command comes in two flavors:
(1) either you have all your values available, as literals or SQL Server variables - in that case, you can use the INSERT .. VALUES() approach:
INSERT INTO dbo.Iplayerds (IplayerName, Sname, WeightLBs)
VALUES (#IplayerName, #Sname, #WeightLBs)
Note: I would recommend to always explicitly specify the list of column to insert data into - that way, you won't have any nasty surprises if suddenly your table has an extra column, or if your tables has an IDENTITY or computed column. Yes - it's a tiny bit more work - once - but then you have your INSERT statement as solid as it can be and you won't have to constantly fiddle around with it if your table changes.
(2) if you don't have all your values as literals and/or variables, but instead you want to rely on another table, multiple tables, or views, to provide the values, then you can use the INSERT ... SELECT ... approach:
INSERT INTO dbo.Iplayerds (IplayerName, Sname, WeightLBs)
SELECT
[IplayerName], [Sname], [WeightLBs]
FROM
OPENJSON(#json) WITH (IplayerName NVARCHAR(200),
Sname NVARCHAR(20),
WeightLBs DECIMAL(10,4)
)
Here, you must define exactly as many items in the SELECT as your INSERT expects - and those can be columns from the table(s) (or view(s)), or those can be literals or variables. Again: explicitly provide the list of columns to insert into - see above.
You can use one or the other - but you cannot mix the two - you cannot use VALUES(...) and then have a SELECT query in the middle of your list of values - pick one of the two - stick with it.
I want to create a procedure that creates a course for a user this takes one parameter that is userid and the other value will be selected from tbl_chapter.there are 27 chapters that are going to be selected and 27 inserts will be executed .insert is going to be like INSERT INTO tbl_user_chapter(user_id,chapter_id) VALUEs (9 , 1),(9,2),(9,3),....
I want something like this:
CREATE PROCEDURE createCourse (IN userid_param int)
BEGIN
INSERT INTO tbl_user_chapter(tbl_user_chapter.user_id,tbl_user_chapter.chapter_id) VALUE(userid_param , SELECT id FROM tbl_chapter)
END
SELECT id FROM tbl_chapter will be multiple rows.
I know this is wrong and I need help.
if there is a better way to do this please let me know.
If the select does not return one row, then don't use the VALUES( ) syntax. Use INSERT ... SELECT syntax:
CREATE PROCEDURE createCourse (IN userid int)
BEGIN
INSERT INTO tbl_user_chapter(user_id,chapter_id)
SELECT userid, id FROM tbl_chapter;
END
Make sure userid does NOT conflict with a column of the same name in your tbl_chapter table. If a column exists with that name, you should change the IN parameter of the stored procedure.
I have sql table with data as below
SnackID Name
1 Chicken
2 Soda
3 Chocolate
4 IceCream
I have the below user-defined function which accepts arguments as a string with multiple values like 'Chicken', 'Soda'.
CREATE FUNCTION GetSnackCodes
(
#myValues varchar(max)
)
RETURNS #SnacksCodes TABLE
(
mySnackCoded int NULL
)
AS
BEGIN
insert into #SnacksCodes
select SnackID from Snack where Name In (#myValues)
return ;
END;
GO
When I tried to invoke this function by passing multiple values to this variable I am not getting expected result.
I guess it's trying to search multiple (comma separated )values as a single value.
Any other possible workaround for how to pass this values?
Your guess is correct - when you pass a single string with comma-separated values, SQL server treats it as a single string value.
Use table valued parameter instead:
CREATE TYPE SnackCode As Table (
Name NVARCHAR(50)
);
GO;
CREATE FUNCTION GetSnackCodes (
#myValues SnackCode
)
RETURNS #SnacksCodes TABLE (
mySnackCoded int NULL
)
AS
BEGIN
insert into #SnacksCodes
select SnackID
from Snack
where Name In (select Name from #myValues)
return ;
END;
GO
you can split comma separated value and store that in temporary table then pass that table value result to query
I have a database with a couple of tables. I need to add a column in one table after the insertion of a new row in another table.
Table A: id | Type | Category | ShortDesc | LongDesc | Active
Row 1 int(11), varchar, varchar,varchar,varchar,int
Row 2
Row 3
Table B: id | Row1-ShortDesc | Row2-ShortDesc | Row3-ShortDesc
Row 1 int(11), tiny(1), tiny(1), tiny(1) etc...
Row 2
Row 3
When I occasionally add a new row (item) to TableA, I want a new column in TableB. TableA is a long evolving collection. A Row in TableA can not be removed for obvious legacy reasons.
So when I insert a row to TableA I need to have another column inserted/appended into TableB.
Any help would be appreciated.
TIA.
Answer derived from training in SQL
I was finally able to derive and create my trigger solution utilizing a class in SQL Server at MAX TRAINING in CINCINNATI OHIO.
--SQL CODE
-- Create a table called TableA that just holds some data for the trigger
-- This table has a primary Key seeded with 1 and incremented by 1
CREATE TABLE TableA(
id int identity(1,1) PRIMARY KEY,
name varchar(60) NOT NULL,
shortDesc varchar(60) NOT NULL,
longDesc varchar(60) NOT NULL,
bigDesc TEXT NOT NULL
)
GO
-- Create a table TableB that only has a ID column. ID as a primary key seeded with 1, incremented by 1
CREATE TABLE TableB(
id int identity(1,1) PRIMARY KEY
)
GO
-- Just to see the two tables with nothing in it.
select * from TableA
select * from TableB
GO
-- The actual trigger in TableA based upon an insert
CREATE TRIGGER TR_myInserCol
ON TableA
AFTER INSERT
AS
BEGIN
-- Don't count the trigger events
SET NOCOUNT ON;
-- Because we are making strings we declare some variables
DECLARE #newcol as varchar(60);
DECLARE #lastRow as int;
DECLARE #sql as varchar(MAX);
-- Now fill the variables
-- make sure we are looking at the last, freshly inserted row
SET #lastRow = (SELECT COUNT(*) FROM TableA);
-- Make a SELECT statement for the last row
SET #newcol = (SELECT shortDesc FROM TableA WHERE id = #lastRow);
-- Adds a new column in TableB is inserted based on a
-- TableA.shortDesc as the name of the new column.
-- You can use any row data you want but spaces and
-- special characters will require quotes around the field.
SET #sql = ('ALTER TABLE TableB ADD ' + #newcol + ' char(99)');
-- And run the SQL statement as a combined string
exec(#sql);
END;
GO
--Insert a new rows into TableA
--The trigger will fire and add a column in TableB
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('attract','Attraction','Attractions','Places to go see and have
fun');
GO
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('camp','Camp','CAMP GROUND','Great place to sleep next to a creek');
GO
(name,shortDesc,longDesc,bigDesc)
VALUES ('fuel','GasStation','Fueling Depot','Get gas and go');
GO
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('petstore','PetStore','Pet Store','Get a friend');
GO
-- See the newly created rows in TableA and the new Columns created in TableB
select * from TableA
select * from TableB
GO
-- Do not execute unless you want to delete the newly created tables.
-- Use this to delete your tables
-- Clean up your work space so you can make changes and try again.
DROP TABLE TableA;
DROP TABLE TableB;
GO
Thanks again to those that tried to help me out. And yes, I still understand this may not be the best solution but for me this works as I will only insert rows in TableA maybe a couple of times a year and will more than likely max out with less than 300 rows over the next several years as the data I am working with doesn't change that frequently and have a single row to access with a single bit (T/F) allows me to now quickly assign TableB's to locations and people for their search criteria and to generate a nice SQL query string without multiple reads across potentially several pages. Thanks again!
And if someone wants to add or modify what I have done, I'm all ears. It's all about learning and sharing.
Michael
how to write query for following request?
my table:
id designation
1 developer,tester,projectlead
1 developer
1 techlead
if id=1,designation="'developer'"
Then need to first,second records.Because 2 rows are having venkat.
if id=1,designation="'developer','techlead'" then need to get 3 records as result.
i wrote one service for inserting records to that table .so that i am maintaining one table to store all designation with same column with comas.
By using service if user pass id=1 designation="'developer','techlead'" then need to pull the above 3 records.so that i am maintaining only one table to save all designations
SP:
ALTER PROCEDURE [dbo].[usp_GetDevices]
#id INT,
#designation NVARCHAR (MAX)
AS
BEGIN
declare #idsplat varchar(MAX)
set #idsplat = #UserIds
create table #u1 (id1 varchar(MAX))
set #idsplat = 'insert #u1 select ' + replace(#idsplat, ',', ' union select ')
exec(#idsplat)
Select
id FROM dbo.DevicesList WHERE id=#id AND designation IN (select id1 from #u1)
END
You need to use the boolean operators AND and OR in conjunction with LIKE:
IF empid = 1 AND (empname LIKE '%venkat%' OR empname LIKE '%vasu%')
The above example will return all rows with empid equals 1 and empname containing venkat or vasu.
Apparently you need to create that query based on the input from user, this is just an example of how the finally query should look like.
Edit: Trying to do this within SqlServer can be quite hard so you should really change your approach on how you call the stored procedure. If you can't do this then you could try and split your designation parameter on , (the answers to this question show several ways of how to do this) and insert the values into a temporary table. Then you can JOIN on this temporary table with LIKE as described in this article.