Passing parameter to a SQL Server stored procedure - sql-server

I am trying to write a SQL query and that works, but the stored procedure is not working when I try with parameters.
Example :
select *
from Table1
where Name = 'BEST People' // this works
// this does not show any rows
declare #Name nvarchar(128)
set #Name= 'BEST People'
select *
from Table1
where Name = #Name
Even when I try with a stored procedure, it does not work.

Depending on your column collation String Comparison Work
Specify Your Question Like This
Here's how you would check your column collation:
DECLARE #TableId INT
SELECT #TableId=id FROM sys.sysobjects
WHERE xtype='U' AND name='Table1'; --Your table name here
SELECT name, collation_name FROM sys.columns
WHERE object_id=#TableId AND name=N'Name'; --Your column name here
View Collation Information

You need to cast the string to NVARCHAR:
declare #Name nvarchar(128)
set #Name= N'BEST People'
select * from Table1 where Name = #Name
Without the N it will be a VARCHAR

Related

Execute 2 queries that are in 2 variables and store the result in other 2 variables

As mentioned in the question, I want to store the results of these queries into other variables so that I can compare the output and find the ones which are not matching. Please help me out with it. The variable #Stagename consists of the first query and variable #correctname consists of the second query. I found some answers of storing them into a table variable but it is not working. These queries are not a single query and hence are stored in the form of rows of a table and are being fetched by the cursor. I've passed the second variable #tablename which I want as the final output but only of the ones in whom the comparison is not matching. I've used the following code:
DECLARE #Stagename VARCHAR(MAX)
DECLARE #correctname VARCHAR(MAX)
DECLARE #tablename VARCHAR(MAX)
--DECLARE #StageCount VARCHAR(max)
--DECLARE #IndexCount VARCHAR(MAX)
DECLARE #Table1 TABLE (StageCount Varchar(max), TableName VARCHAR(MAX))
DECLARE #Table2 TABLE (IndexCount Varchar(max), TableName VARCHAR(MAX))
--DEALLOCATE IF EXISTS CS_StagingIndex
DECLARE CS_StagingIndex CURSOR FOR
SELECT StageCount, CorrectCount, TableName FROM bak.StagingindexesQuery
OPEN CS_StagingIndex
FETCH NEXT FROM CS_StagingIndex
INTO #Stagename,#Correctname,#tablename
WHILE ##Fetch_Status = 0
BEGIN
INSERT INTO #Table1(StageCount,TableName) VALUES (exec(#StageName),#tablename);
INSERT INTO #Table2(IndexCount,TableName) VALUES (exec(#CorrectName),#tablename);
--Select * from #Table1 Ignore this.
FETCH NEXT FROM CS_StagingIndex
INTO #Stagename,#Correctname,#tablename
END
CLOSE CS_StagingIndex
DEALLOCATE CS_StagingCursor
Select count(1) from stg.LogisticsElectronicAddres - This is the query stored in #StageName.
select count(1) from (select distinct recid1 from stg.LogisticsElectronicAddress) x - This is the query stored in #IndexName.
LogisticsElectronicAddress and this is the tablename.
Now if for example, the result of StageName query is 2000 and the result of Correctname is also 2000, then the tablename should not be printed. But if the results dont match, then I want the tablename to be printed. There are multiple rows in bak.StagingIndexesQuery table that contain such queries for multiple tables.
I don't believe that's the correct EXEC syntax for sql-server; I don't think that is going to work.
What you can do is use the statement .. INSERT table EXEC storedprocName.
However, there are constraints - the table layout must match that of the return procedure in terms of column count/order/data types/length ( within reason, ie if a column in the table is NVARCHAR(100) and the stored procedure returns that column as NVARCHAR(105), that should be fine - unless of course the data itself exceeds the 100 length). I believe column names are ignored for INSERT/EXEC
Also, if the query being executed has an INSERT/EXEC , this will not work (only one allowed at anyone time)
So you will need to use dynamic SQL...
DECLARE #MySQLStatement NVARCHAR(400)
DECLARE #MyStoedProcName NVARCHAR(100)
DECLARE #Table1 TABLE (StageCount Varchar(max), TableName VARCHAR(MAX))
SET #MySQLStatement = 'INSERT #Tablename EXEC ' + #StoredProcedure
EXEC sp_ExecuteSQL #MySQLStatement
Now off the top of my head, I can't remember if that #Table1 will be in the scope of that dynamic SQL statement. If it isn't, make #Table1 a temp table (ie create table #table1 [ ... etc ] )

How to get the datatype of a column of a view in SQL Server?

I want to get the datatype of a column of a view in SQL Server. Is there an efficient way to do that?
I have to get the Database Name, Schema, View Name all dynamically from one database, look for the view in another database and find the data type of the column in the third database.
E.g.
SELECT #db2 = Name FROM db1.schema.databases
SELECT #c = Name FROM db1.schema.columns
SELECT #v = Name FROM db1.schema.views
SELECT #datatype = query to get {datatype} of column {c} from {db2}.{schema}.{v}
Here column {c} of {db2}.{schema}.{v} can refer another database say {db3}
Please suggest.
Don't know exactly what you need, but this might help you:
USE master;
GO
CREATE VIEW dbo.TestView AS
SELECT * FROM master..spt_values;
GO
--This is the view's output
SELECT * FROM dbo.TestView;
GO
--Set your variables
DECLARE #db2 VARCHAR(100) = 'master';
DECLARE #c VARCHAR(100) = 'type';
DECLARE #vSchema VARCHAR(100) = 'dbo';
DECLARE #vName VARCHAR(100) = 'TestView'
--The query will display the DATA_TYPE and all other columns returned by INFORMATION_SCHEMA.COLUMNS
SELECT c.DATA_TYPE
,c.*
FROM master.INFORMATION_SCHEMA.COLUMNS AS c
WHERE c.TABLE_NAME=#vName
AND c.TABLE_SCHEMA=#vSchema
AND c.COLUMN_NAME=#c
AND c.TABLE_CATALOG=#db2; --forgot this in the first post...
--Clean-Up
GO
DROP VIEW dbo.TestView;
It's a bit fuzzy, that the COLUMNS view returns tables and views as if they were the same. The advantage: You can use the same approach to check a table's column...
Hint: This INFORMATION_SCHEMA.COLUMNS is just a built-in view looking into the corresponding sys tables.

How to INSERT INTO table column with string/variable

This is the data I have pulled from powershell and inserted it into a #temptable:
Name : SULESRKMA
Location : Leisure Services - Technology Services
Shared : False
ShareName :
JobCountSinceLastReset : 0
PrinterState : 131072
Status : Degraded
Network : False
I'm while looping through the data and have stripped the values from the identifiers. I'd like to use these identifiers to insert the values into a table with identical Column names to the identifiers. So for example, I have a variable called #identifier = "Name" and a temp table #printers with a column name of Name. I'd like to do something like:
SELECT --select statement
INSERT INTO #printers(#identifier)
But This doesn't seem to work, unsurprisingly. Is there a way to accomplish this? (The #identifier variable will be changing to the other identifiers in the data throughout the course of the while loop.)
Any alternate suggestions that don't even involve using this sort of method are welcome. My ultimate goal is just to get this data as a row into a table.
(I'm currently using Microsoft SQL Server Management Studio if that matters)
First, it's unlikely you need to loop over anything in this situation. Think set based operations when you think about SQL.
INSERT INTO #temptable (Column1Name, Column2Name, Column3Name)
VALUES (#identifer, #anotherIdentifier, #someOtherIdentifier)
--optional clauses
WHERE Column1Name = 'some value' OR Column1Name = #someIdentifier
Or you can SELECT INTO
SELECT
#identifier,
#anotherIdentifer,
#someOtherIdentifier
INTO #temptable
It's important that you have a value in your SELECT INTO for each column in the table which you are trying to add the data to. So, for example, if there were 4 columns in #temptable and you only had 3 values to insert (columns 1, 2 , and 3) then you'd need to NULL column 4 or set it statically.
SELECT
#identifier,
#anotherIdentifer,
#someOtherIdentifier,
NULL
INTO #temptable
--or
SELECT
#identifier,
#anotherIdentifer,
#someOtherIdentifier,
'static value'
INTO #temptable
EDIT
If you want to use a varible to speciy the column that you want to insert into, you have to use dynamic sql. Here is an example:
if object_id ('tempdb..#tempTable') is not null drop table #tempTable
create table #tempTable (Column1Name int, Column2Name int, Column3Name int)
declare #columnName varchar(64) = 'Column1Name'
declare #sql varchar(max)
set #sql =
'insert into #tempTable (' + #columnName + ')
select 1'
exec(#sql)
select * from #tempTable

Select values from SQL table - leave specific column names (name condition)

I have SQL table like this:
create table [Tbl](
[_Id] int Identity(1, 1),
[_ProjectId] int,
[Name] varchar(255),
[Age] int
...
Primary Key([_Id])
)
I need to select all values but not from the columns which names started by "_" (_Id, _ProjectId). How can I do it?
(For understanding: I have many tables like this with their specific columns. I don't know all the colum names).
You list the columns you want in the column list of your query. Don't add the columns that begins with a _.
Update:
You can build the query dynamically in for example a stored procedure where you have table name as a parameter. Use the sys.columns to get the column names and exclude the columns you don't want.
create procedure YourProcedure
#TableName sysname
as
declare #SQL nvarchar(max)
set #SQL = '
select '+stuff((select ','+quotename(name)
from sys.columns
where object_id = object_id(#TableName) and
left(name, 1) <> '_'
for xml path(''), type).value('text()[1]', 'sysname'),1,1,'')+'
from '+quotename(#TableName)
exec sp_executesql #SQL
SQL Fiddle
You can't use wildcards on column names.
Either select all with
select * from table
or specify which columns you want to select witt their full name
select name, age from table
List the columns you want separated by commas , instead of *
SELECT Name, Age, Col3, Col4, ColN FROM Tb1

SQL Server: Put stored procedure result set into a table variable without specifying its schema

I have a stored procedure with many parameters.
I want to insert (or maybe select) like this:
INSERT INTO #TEMP_TABLE
EXECUTE STORED_PROCEDURE
without defining the schema of #TEMP_TABLE.
for example:
declare #temptable2 as table
(
DatabaseName nvarchar(128),
dbsize nvarchar(128),
owner varchar(128),
dbid nvarchar(128),
created nvarchar(128),
status nvarchar(128),
compatibility_level nvarchar(128)
)
INSERT INTO #temptable2
EXEC ('sp_helpdb')
You cannot do this with a #tablevariable.
The work around in the link posted by Joe uses SELECT ... INTO.
This is not currently supported by table variables (and won't ever be from the response to this connect item) as the schema for table variables needs to be known at compile time.
The only way to acheive this is to use a hooky workaround of SELECT INTO a #temp table, which will be more trouble than it is worth.
just code the table variable with the columns that are needed. then add a very visible, well located comments into both stored procedures reminding the coder of this dependency and just move on to other endeavors.
CREATE PROCEDURE [dbo].[Sp_TestA](#P1 AS VARCHAR(50), #P2 AS VARCHAR(50),#P3 AS VARCHAR(50)) AS BEGIN
SELECT '1' AS Col1,#P1 AS Col2,#P2 AS Col3,#P3 AS Col4 UNION
SELECT '1' AS Col1,'A1' AS Col2,'A2' AS Col3,'A3' AS Col4 UNION
SELECT '2' AS Col1,'B1' AS Col2,'B2' AS Col3,'B3' AS Col4 UNION
SELECT '3' AS Col1,'C1' AS Col2,'C2' AS Col3,'C3' AS Col4 UNION
SELECT '4' AS Col1,'D1' AS Col2,'D2' AS Col3,'D3' AS Col4;
END
Declare #TblRtRcs TABLE(Col1 VARCHAR(50)NOT NULL,Col2 VARCHAR(50) NOT NULL,Col3 VARCHAR(50) NOT NULL,Col4 VARCHAR(50) NOT NULL);
DECLARE #Sql AS VARCHAR(MAX);
SET #Sql='EXEC [Sp_TestA #P1=''xA'',#P2=''xB'',#P3=''xC''';
INSERT INTO #TblRtRcs(Col1,Col2,Col3,Col4) EXEC(#Sql);
SELECT * FROM #TblRtRcs;
This #skorpk answer actually strikes me like the correct answer to the question asked. Indeed you can insert into table variables as the question seems to indicate. Furthermore you could also do it with stored procedures that
expect parameters. See sample code below:
This answer actually strikes me like the correct answer to the question asked. Indeed you can insert into table variables as the question seems to indicate. Furthermore you could also do it with stored procedures that
expect parameters. See sample code below:
/*Create stored procedure for this example. */
/*It will simulate results and we can clean it up */
/*later in this example */
create proc sproc_get_friends (#context_user_id int)
as
select #context_user_id as id, 'me' as name
union all select 1234678910 as id, 'Jane Doe' as name
union all select 1112131415 as id, 'John Doe' as name
go
/*Create temp variable*/
declare #tmp as table ( friend_user_id int, friend_name nvarchar(100) )
/*Insert into temp variable from stored procedure*/
INSERT INTO #tmp exec ('sproc_get_friends 10000')
/*Show data in temp variable*/
select * from #tmp
go
---Clean up
drop proc sproc_get_friends
go

Resources