May I ask on how do we execute Dynamic Select Query?
Basically what I want to achieve is a dynamic select that can SELECT a query based on a dynamic column, and that dynamic column is existing in a table.
Example Table
Table Name: AppleBox
Table Columns: Apple101, Apple102, Apple103
Table Row:
Apple101 = 1,2,3,4,5
Apple102 = 1,2,
Apple103 = 1
Supposed that I would run a query based on the example
SELECT apple+'$applecode' FROM AppleBox
with $applecode being from an external source, and $applecode = 101, and my expected query would be.
SELECT apple101 FROM AppleBox
Is there a simple way to do this?
Please check below code.
CREATE TABLE [dbo].[AppleBox](
[Apple101] [varchar](50) NULL,
[Apple102] [varchar](50) NULL,
[Apple103] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[AppleBox] ([Apple101], [Apple102], [Apple103]) VALUES (N'1,2', N'1', N'1')
INSERT [dbo].[AppleBox] ([Apple101], [Apple102], [Apple103]) VALUES (N'3,4,5', N'1,2,', N'2')
INSERT [dbo].[AppleBox] ([Apple101], [Apple102], [Apple103]) VALUES (N'1,2,3,4,', N'1,2,3', N'3')
INSERT [dbo].[AppleBox] ([Apple101], [Apple102], [Apple103]) VALUES (N'1,2,3,4,5', N'1', N'4')
GO
DECLARE #query NVARCHAR(500)
DECLARE #exparam NVARCHAR(50)
SET #exparam='101'
SET #query='SELECT Apple'+#exparam+' FROM dbo.AppleBox'
EXECUTE sp_executesql #query
You can use a case expression:
select (case when $applecode = 101 then apple101
when $applecode = 102 then apple102
when $applecode = 103 then apple103
end) as apple
from t;
You would only need dynamic SQL (in this case) if your query could return a variable number of columns or if you wanted to set the name of the column. Neither seems important.
Related
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
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;
Please Check this Sample Sql fiddle:http://www.sqlfiddle.com/#!3/f59ae.
In this way only i want output.first 2 columns Should contain values that can be anything
and rest columns should contain Hello values without considering Create Table statement.
I want to write a query that will insert 2 values into 2 columns and Hello into all other columns.
Suppose I have 100 columns then I want 10 and 20 values to be inserted into col1 and col2 and Hello into all other 98 columns.
Likewise if I have 200 columns then I want 10 and 20 values to be inserted into col1 and col2 and Hello into the other 198 columns.
I have written a query which but I thought it's a basic query so I am not writing here. So downvoters please consider that.
How to write this query???
You can do this by just adding the Default constraint to column's which you don't want to insert values explicitly. I hope #Manish Pant's answer should help you to do that.
Based on your comments you want do this only by using query. So you need to use Dynamic sql to do this.
Simple Demo
Schema
CREATE TABLE [dbo].[Test](
[id] [int] IDENTITY(1,1) NOT NULL,
[Country] [varchar](100) NULL,
[State] [varchar](100) NULL,
[City] [varchar](100) NULL,
[Population (in Millions)] [varchar](100) NULL
)
Declare a variable to hold the Dynamic sql
DECLARE #cl_val NVARCHAR(max)='Insert into Test('
Pull all the columns from sys.columns view and filter the identity column
SELECT #cl_val += Quotename(NAME) + ','
FROM sys.columns
WHERE Object_name(object_id) = 'Test'
AND is_identity <> 1
ORDER BY NAME
SELECT #cl_val = LEFT(#cl_val, Len(#cl_val)-1) + ') values (' -- Remove the trailing comma
Here add the values only to the column in case statement which you are explicitly passing value in else part add the default value
SELECT #cl_val += CASE
WHEN NAME ='City' THEN '''A'''
WHEN NAME='country' THEN '''c'''
ELSE '''Hello'''
END + ','
FROM sys.columns
WHERE Object_name(object_id) = 'Test'
AND is_identity <> 1
ORDER BY NAME
SELECT #cl_val = LEFT(#cl_val, Len(#cl_val)-1) + ')' -- Remove the trailing comma
--PRINT #cl_val
EXEC Sp_executesql #cl_val
select * from test
Result
id Country State City Population (in Millions)
-- ------- ----- ---- ------------------------
1 c Hello A Hello
If All other columns are set as Nullable then into your Insert statement you can write statement By without considering your Nullable fields.
Suppose for example your Table named Student with properties is:
Student ::
Name,
RollNo,
OptionalField_1,
OptionalField_2,
OptionalField_3
where columns with OptionalField are Nullble fields.
In this case you can write your Query simply as ::
INSERT INTO Student (Name,RollNo) VALUES ('MyName',12);
So this will make an ENtry with two column values & all remaining as Nullable.
For your better understandings you can refer :: http://www.w3schools.com/sql/sql_insert.asp
You can use this for your query:
create table mytable(
col1 varchar not null,
col2 varchar not null,
col3 varchar not null default 'Hello',
col4 varchar not null default 'Hello',
col5 varchar not null default 'Hello',
so on...... );
insert into mytable(col1,col2) values('10','20');
I have a table of more than 2 million rows and over 100 columns. I need to run a query that checks if there are any null values in any row or column of the table and return an ID number where there is a null. I've thought about doing the following, but I was wondering if there is a more concise way of checking this?
SELECT [ID]
from [TABLE_NAME]
where
[COLUMN_1] is null
or [COLUMN_2] is null
or [COLUMN_3] is null or etc.
Your method is fine. If your challenge is writing out the where statement, then you can run a query like this:
select column_name+' is null or '
from information_schema.columns c
where c.table_name = 'table_name'
Then copy the results into a query window and use them for building the query.
I used SQL Server syntax for the query, because it looks like you are using SQL Server. Most databases support the INFORMATION_SCHEMA tables, but the syntax for string concatenation varies among databases. Remember to remove the final or at the end of the last comparison.
You can also copy the column list into Excel and use Excel formulas to create the list.
You can use something similar to the following:
declare #T table
(
ID int,
Name varchar(10),
Age int,
City varchar(10),
Zip varchar(10)
)
insert into #T values
(1, 'Alex', 32, 'Miami', NULL),
(2, NULL, 24, NULL, NULL)
;with xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' as ns)
select ID,
(
select *
from #T as T2
where T1.ID = T2.ID
for xml path('row'), elements xsinil, type
).value('count(/row/*[#ns:nil = "true"])', 'int') as NullCount
from #T as T1
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')