the multi-part identifier "#tmpFullname.Item" could not be bound." - tsql

The following code is supposed to take a string that may or may not be comma delimited and put it into a table (#tmpFullanme) that part works flawlessly. The second part is supposed return all the values that are LIKE / NOT LIKE with or without % symbols based on what is input. The error that I am getting is "the multi-part identifier "#tmpFullname.Item" could not be bound." The best guess I have is that it may be out of scope?
DROP PROCEDURE uspJudgments;
GO
CREATE PROCEDURE uspJudgments
#fullName varchar(100), #SrchCriteria1 varchar(15), #SrchCriteria2 varchar(15), #qualifier varchar(10)
AS
BEGIN
SELECT *
INTO #tmpFullname
FROM dbo.DelimitedSplit8K(#fullName, ',')
DECLARE #Query NVarChar(1024)
SET #Query = 'SELECT d.*' + ' FROM defendants_ALL d, #tmpFullname' +
' WHERE d.combined_name' + ' ' + #qualifier + ' ' + '''' + #SrchCriteria1 + '''' + ' + ' + '''' + #tmpFullname.Item + '''' + ' + ' + '''' + #SrchCriteria2 + ''''
END
EXEC sp_executesql #Query
PRINT(#Query)
IF OBJECT_ID('#tmpFullname', 'U') IS NOT NULL
DROP TABLE #tmpFullname
EXEC uspJudgments #qualifier = 'LIKE', #fullName = 'johnson', #SrchCriteria1 = '%', #SrchCriteria2 = '%'
Cannot get to the PRINT output as "the multi-part identifier "#tmpFullname.Item" could not be bound." If I change #tmpFullname.Item to '#tmpFullname.Item it goes through and returns nothing but it shows that the query is correct minus the issue with that table.
SELECT d.* FROM defendants_ALL d, #tmpFullname WHERE d.combined_name LIKE '%' + '#tmpFullname.Item' + '%'
Please note that until I made this into a dynamic query so I can change the statement from LIKE to IN etc it worked very well.

I set up a full test to get the proper script to get you your desired results. I also have a SQL Fiddle showing how this works. Note You will want to run EXECUTE sp_executesql #Query inside the stored procedure
ALTER PROCEDURE uspJudgments #fullName varchar(100)
, #SrchCriteria1 varchar(15)
, #SrchCriteria2 varchar(15)
, #qualifier varchar(10)
AS
BEGIN
--Simulates your split function
SELECT *
INTO #tmpFullName
FROM
(
SELECT 'firstTest' AS Item
UNION ALL SELECT 'secondTest'
UNION ALL SELECT 'NotThere'
) AS t;
DECLARE #Query NVARCHAR(1024);
SELECT #Query = 'SELECT d.* '
+ ' FROM defendants_ALL d '
+ ' CROSS JOIN #tmpFullName AS t '
+ ' WHERE d.combined_name' + ' ' + #qualifier + ' '
+ '''' + #SrchCriteria1 + ''''
+ ' + ' + 't.Item' + ' + ' + '''' + #SrchCriteria2 + '''';
EXECUTE sp_executesql #Query;
END
EXECUTE uspJudgments
#fullName = 'does not matter'
, #SrchCriteria1 = '%'
, #SrchCriteria2 = '%'
, #qualifier = 'LIKE';

You have to use the tempdb prefix in this case
insert into tempdb..#TABLENAME
and
set #query = 'select * from tempdb..#TABLENAME'

Well, After my last answer i have found several things..
When i look into your procedure you start with the "BEGIN", next you do a insert into the "#tmpFullName" table, your declare the "#Query" variable and create a select statement.
After that you do and "END" with logic after it. You do the "sp_executesql" after that you drop the temptable and you do and EXEC of the current procedure..
The Structure isn't all that readable, sorry to tell you. So maybe you go there first.
Beside a strange structure you are using the "#tmpFullName.Item" in some dynamic SQL as a parameter, while it is declared inside the SQL query it self. So you have to do something like this :
SET #Query = 'SELECT d.*' + ' FROM defendants_ALL d, #tmpFullname' +
' WHERE d.combined_name' + ' ' + #qualifier + ' ' + '''' + #SrchCriteria1 + '''' + ' + ' + ' #tmpFullname.Item ' + ' + ' + '''' + #SrchCriteria2 + ''''
Where the "#tmpFullName.Item" resides insde the code, not as a parameter. But then again, what are you trying to achieve here? To answer this completly we have to know what the other variables are. Your structure isn't telling me what are trying to achieve..
I really can't make any more out of it...

Related

SQL Server 2012: Dynamic crosstab in stored procedure

Im trying to use a stored procedure to create a pivot table between two declared variables #rvar (as rowvariable) and #cvar (as columnvariable). The point is to call the stored procedure from VBA using these two as dynamic input when executing the stored procedure.
My code has three parts:
creating test-data
declaring locals
finding names of columns in crosstab an storing in new local #sql1
executing crosstable with the pivotfunction using the names stored in #sql1.
My problem: The code below works but I would like to make it dynamic regarding the variable defining the column structure - currently set to "q10_1_resp" - so that I only have to declare the local #cvar and use that in part 3 (like in part 4). I have succeeded in making part 3 into a sql-string with subsequent execution but then the column names stored in #sql1 cannot be used in the code in part 4 (I guess it is a scope thing).
--Part 1
create table [user].[test]
(rowvar nvarchar(max),
q10_1_resp int,
q10_2_resp int)
GO
INSERT [user].[test]
VALUES ('PH',1,2),
('PH',2,3),
('EA',1,5),
('EA',5,4),
('PH',3,4),
('PH',6,6),
('EA',4,1),
('PH',5,3),
('PH',2,1)
GO
-- Part 2
declare #rvar as nvarchar(max) = 'rowvar'
declare #cvar as nvarchar(max) = 'q10_1_resp' --this input should be dynamic as well
declare #sql1 as nvarchar(max)= ''
declare #sql2 as nvarchar(max)= ''
-- Part 3
select #sql1 = #sql1 + [a].[col] + char(44)
from
(select distinct QUOTENAME(q10_1_resp) as [col]
from [user].[test]
group by q10_1_resp) as a
SET #sql1 = left(#sql1, len(#sql1) - 1)
-- Part 4
SET #sql2 = 'select ' +
+ #rvar + ','
+ #sql1
+ ' from (Select '
+ #rvar + ', '
+ #cvar
+ ' from [user].[test]) sq pivot(count('
+ #cvar
+ ') for '
+ #cvar + ' IN ('
+ #sql1
+ ')) as pt'
exec sp_executesql #sql2
After a great deal of trying to globalize the scalarvariable without success using a temporary table to store the string was the key. The temporary table created at the beginning of the stored procedure can be assigned and referenced the entire time of the procedure. Thus assigning within execution of #sql and then referencing the string at execution of #sql2. I hope it makes sense.
CREATE PROCEDURE [dbo].[sp_crosstab]
-- Add the parameters for the stored procedure here
#rvar nvarchar(max) = '',
#cvar nvarchar(max) = '',
#data nvarchar(max) = '',
#sql nvarchar(max) = '',
#sql2 nvarchar(max) = '',
#sql3 nvarchar(max)=''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
create table #temp_crosstab
(
sqlstr nvarchar(max)
)
set #sql ='
declare #sql1 nvarchar(max) = char(00)
select #sql1 = #sql1 + [a].[col] + char(44)
from
(select distinct QUOTENAME(' + #cvar + ') as [col]
from ' + #data + '
group by ' + #cvar + ') as a
SET #sql1 = left(#sql1, len(#sql1) - 1)
insert into #temp_crosstab values (#sql1)'
execute sp_executesql #sql
select #sql3 = [sqlstr] from #temp_crosstab
set #sql2 = '
select ' + #rvar + char(44) +
#sql3 + 'from (Select '
+ #rvar + char(44) + ' '
+ #cvar
+ ' from ' + #data + ') sq pivot(count('
+ #cvar
+ ') for '
+ #cvar + ' IN ('+#sql3+')) as pt'
exec sp_executesql #sql2
END
GO

Tsql setting string variable across multiple lines

This is real weird.
when I trace through this code, on the first statement, I am getting #str as a valid insert statement when it is coded as a single line, but when I set #str through select statement, accross multiple lines, it holds value of nothing.
Its really flakey, because some of my inserts worked, and some didn't.
Any ideas how to set the variable properly across multiple lines? Or is this a Microsoft bug...?
UPDATE: Same thing happens when I edit the multi-line t-sql Select into a one line statement
#str, when tracing the code, often turns out to be blank, when it seems like it should not be blank...(the second instance of #str...
Select #str = 'Insert into CustShip Values (' + '''' + #A_Cust_No + '''' + ', ' + '''' + #Ship_To_Id + '''' + ',3)'
EXEC(#str)
Select #str = 'Insert into ShipTo Values ....'
This Second #str is often evaluated to blank....)
ALTER Procedure [dbo].[RefreshCustShip3]
AS
Begin /* Begin Proc */
Set NoCount On
--Delete from CustShip
DECLARE #SHIP_TO_NAME VarChar(255),
#A_Cust_No varchar(255),
#SHIP_TO_ADD1 VarChar(255),
#SHIP_TO_ADD2 VarChar(255),
#SHIP_TO_ADD3 VarChar(255),
#CITY VarChar(255),
#STAT VarChar(255),
#ZIP_Code VarChar(255),
#SHIP_TO_ID VarChar(255),
#COUNTRY VarChar(255),
#ShipId varchar(255),
#str varchar(1000)
DECLARE C CURSOR FAST_FORWARD /* read only, forward only */ FOR
SELECT
A#CUST#NO,
CUST#NAME as SHIP#TO#NAME,
SOLD#TO#ADD#1 AS SHIP#TO#ADD#1,
SOLD#TO#ADD#2 AS SHIP#TO#ADD2,
SOLD#TO#ADD#3 AS SHIP#TO#ADD3,
SOLD#TO#CITY AS CITY,
SOLD#TO#STATE AS [STATE],
SOLD#TO#ZIP#CODE AS ZIP#CODE,
CONCAT(LTRIM(RTRIM(A#CUST#NO)), LTRIM(RTRIM(SOLD#TO#ADD#1))) AS SHIP#TO#ID,
COUNTRY#NAME as Country
from Cust left join CustShip on
Cust.A#Cust#No = CustShip.CustNo
WHERE CustShip.ShipToID is Null
OPEN C
FETCH NEXT FROM C INTO #A_Cust_No, #Ship_To_Name, #SHIP_TO_ADD1, #SHIP_TO_ADD2, #SHIP_TO_ADD3, #CITY, #STAT, #ZIP_Code, #SHIP_TO_ID, #Country;
WHILE ##FETCH_STATUS = 0
BEGIN
if #A_Cust_No = '3RGHOU'
begin
print #Ship_To_Id
end
-- do work here BEGIN CODE BLOCK
Select #str = 'Insert into CustShip Values (' + '''' + #A_Cust_No + '''' + ', ' + '''' + #Ship_To_Id + '''' + ',3)'
EXEC(#str)
Select #str = 'Insert into ShipTo Values (' + '''' + #A_Cust_No + '''' + ', '
+ '''' + #Ship_To_Name + '''' + ', '
+ '''' + #Ship_To_Add1 + '''' + ', '
+ '''' + #Ship_To_Add2 + '''' + ', '
+ '''' + #Ship_To_Add3 + '''' + ', '
+ '''' + #City + '''' + ', '
+ '''' + #Stat + '''' + ', '
+ '''' + #ZIP_Code + '''' + ', '
+ '''' + #Ship_To_Id + '''' + ', '
+ '''' + #Country + ''''
+ ',3)'
EXEC(#str)
FETCH NEXT FROM C INTO #A_Cust_No, #Ship_To_Name, #SHIP_TO_ADD1, #SHIP_TO_ADD2, #SHIP_TO_ADD3, #CITY, #STAT, #ZIP_Code, #SHIP_TO_ID, #Country;
End
CLOSE C;
DEALLOCATE C;
End /* End Proc */
GO
I'm thinking out loud here. From looking at your SQL, Is there a possibility that you're running past your limit of VARCHAR(1000) on #Str? You're creating a string that has 10 variables that each could contain 255 characters. That is a total of 2550 characters without your insert statement syntax.
Also, since you're just assign that string to a single variable you should use SET instead of SELECT.
Also, put a semicolon statement terminator after the end of the string before the EXEC statement.
Also as HABO said above a null value in any of those variables would null out the entire string. Coalesce or doing ISNULL(#CITY, '') would fix that.
I think this is best answer, though many thanks to other posters who lead me to the trail. They deserve credit. Not sure if there is way to give them credit or not....
-- do work here BEGIN CODE BLOCK
Select #str = 'Insert into CustShip Values (' + '''' + #A_Cust_No + '''' + ', ' + '''' + #Ship_To_Id + '''' + ',3)'
EXEC(#str)
Select #str2 = 'Insert into ShipTo Values (' +
iif(#A_Cust_No is Null, 'Null', '''' + Replace(#A_Cust_No,'''','''''') + '''')
+ ', ' +
iif(#Ship_To_Name is Null, 'Null', '''' + Replace(#Ship_To_Name,'''','''''') + '''') + ', ' +
iif(#Ship_To_Add1 is Null, 'Null', '''' + Replace(#Ship_To_Add1,'''','''''') + '''') + ', ' +
iif(#Ship_To_Add2 is Null, 'Null', '''' + Replace(#Ship_To_Add2,'''','''''') + '''') + ', ' +
iif(#Ship_To_Add3 is Null, 'Null', '''' + Replace(#Ship_To_Add3,'''','''''') + '''') + ', ' +
iif(#City is Null, 'Null', '''' + Replace(#City,'''','''''') + '''') + ', ' +
iif(#Stat is Null, 'Null', '''' + Replace(#Stat,'''','''''') + '''') + ', ' +
iif(#Zip_Code is Null, 'Null', '''' + Replace(#Zip_Code,'''','''''') + '''') + ', ' +
iif(#Ship_To_Id is Null, 'Null', '''' + Replace(#Ship_To_Id,'''','''''') + '''') + ', ' +
iif(#Country is Null, 'Null', '''' + Replace(#Country,'''','''''') + '''') + ', 3)'
EXEC(#str2)
FETCH NEXT FROM C INTO #A_Cust_No, #Ship_To_Name, #SHIP_TO_ADD1, #SHIP_TO_ADD2, #SHIP_TO_ADD3, #CITY, #STAT, #ZIP_Code, #SHIP_TO_ID, #Country;
End

How can I convert SQL Server data to importable goinstant data?

I'm looking for a way to import a SQL Server table data into goinstant. Is there a JSON editor or script that allows this and that can be clipboard pasted right into goinstant?
I may have come up with a solution. I was able to use a previously created sql to json object tsql script written by Matthew D. Erwin. I modified it to handle creating an importable output to goinstant. See the script here on github, or feel free to grab it from below.
/****** Object: StoredProcedure [dbo].[GetJSON] Script Date: 5/16/2014 9:04:40 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--
-- Author: Matthew D. Erwin (Snaptech, LLC)
-- Create date: May 9, 2013
-- Modified date: May 16, 2014 by Rudy E. Hinojosa (CBM Archives, LLC) rudy.hinojosa#cbmarchives.com
-- Description: Returns the contents of a given table
-- in JavaScript Object Notation JSON -
--
-- Very notably useful for generating MOCK .json files
-- for testing or before RESTful services are completed.
--
-- This implementation:
-- *removed cursor (using FOR XML PATH(''))
-- *properly supports NULL vs quoted values
-- *supports dates in ISO 8601 - presuming UTC
-- *uses Data_Type and Is_Nullable info
-- *escapes '\'
-- *formats output with tabs/newlines
-- *can return final results as XML to bypass
-- truncation in SSMS
-- *supports schema (e.g. [dbo].[TableName]
-- *includes "recordCount" field
-- Options:
-- #table_name: the table to execute the query
-- #limit: equivalent to "select top N * from table"
-- #ssms: flag to use if executing in Sql Server Management Studio
-- to bypass result truncation limits.
-- #isgoinstant: flag to use if importing results to GoInstant database
--
-- Inspired primarily by the 2008 work of Thiago R. Santos which was influenced by Thomas Frank.
-- Usage: [dbo].[GetJSON] #Table_name = 'MySchema.MyTable', #limit = 50, #ssms = 0, #isgoinstant = 0
CREATE procedure [dbo].[GetJSON] (
#table_name varchar(max),
#limit int = null,
#ssms bit = 0,
#isgoinstant bit = 0
)
as
begin
declare #json varchar(max), #query varchar(max), #table_schema varchar(max) = null
if( charindex('.', #table_name) > 0 )
begin
set #table_schema = replace(replace( substring(#table_name, 0, charindex('.',#table_name)), '[', ''), ']', '')
set #table_name = replace(replace( substring(#table_name, charindex('.',#table_name) + 1,len(#table_name)), '[', ''), ']', '')
end
set #query =
'select ' + case when #limit is not null then 'top ' + cast(#limit as varchar(32)) + ' ' else '' end + ''' '' + REVERSE(STUFF(REVERSE(''' +
--case when #isgoinstant is not null then ('"' + cast(newid() as varchar(max)) + '"' + ': { ') else '' end +
CAST((SELECT ' "' + column_name + '" : ' +
case when is_nullable = 'YES'
then ''' + case when [' + column_name + '] is null then ''null'' else ' +
case when data_type like '%binar%' then null else '' end +
case when data_type like 'XM%' then null else '' end +
case when data_type like '%char%' or data_type like '%text%' then '''"'' + ' else '' end +
case when data_type like '%date%' then 'char(34) + convert(varchar(23),[' + column_name + '], 126) + ''Z'' + char(34)' else
'replace(replace(replace(replace(cast([' + column_name + '] as varchar(max)),''\'',''\\''),''"'',''\"''),char(10),''\n''),char(13),''\n'') ' end +
case when data_type like '%char%' or data_type like '%text%' then '+ ''"''' else '' end + ' end + '''
else
case when data_type like '%binar%' then null else '' end +
case when data_type like 'XM%' then null else '' end +
case when data_type like '%char%' or data_type like '%text%' then '"' else '' end +
''' + ' +
case when data_type like '%date%' then 'char(34) + convert(varchar(23),[' + column_name + '], 126) + ''Z + char(34)' else
'replace(replace(replace(replace(cast([' + column_name + '] as varchar(max)),''\'',''\\''),''"'',''\"''),char(10),''\n''),char(13),''\n'') + ''' end +
case when data_type like '%char%' or data_type like '%text%' then '"' else '' end end + ',' AS [text()]
from information_schema.columns where table_name = #table_name and (#table_schema is null or table_schema = #table_schema) FOR XML PATH('') ) as varchar(max)) +
'''),1,1,'''')) + '' }'' as json into tmpJsonTable from ' + #table_name + ' with(nolock) '
exec sp_sqlexec #query
if (#isgoinstant = 0)
set #json =
'{' + char(10) + char(9) +
'"recordCount" : ' + Cast((select count(*) from tmpJsonTable) as varchar(32)) + ',' + char(10) + char(9) +
'"records" : ' + char(10) + char(9) + char(9) + '[' + char(10)
+ REVERSE(STUFF(REVERSE(CAST((SELECT char(9) + char(9) + json + ',' + char(10) AS [text()] FROM tmpJsonTable FOR XML PATH('')) AS varchar(max))),1,2,''))
+ char(10) + char(9) + char(9) + ']' + char(10) + '}'
else
set #json =
'{' + char(10) + char(9) +
REVERSE(STUFF(REVERSE(CAST((SELECT case when #isgoinstant is not null then ('"' + cast(newid() as varchar(max)) + '"' + ': { ') else '' end + char(9) + json + ',' + char(10) AS [text()] FROM tmpJsonTable FOR XML PATH('')) AS varchar(max))),1,2,''))
+ char(10) + char(9) + char(9) + '}'
drop table tmpJsonTable
if( #ssms = 1 and len(#json) > 65535 ) --deal with Sql Server Management Studio text/grid truncation
select cast('<json><![CDATA[' + #json + ']]></json>' as xml) as jsonString
else
select #json as jsonString
end
GO

Export query to text file

What I am trying to do is export a Tsql query to a csv file. Simple enough, however I need to be able to specify which fields are wrapped in quotes "". I can get my query to export with all the feilds wrapped.
"SCHEN001","Joe Bloggs Inc","1","1","1","1","1","1","13","6","Mr John Smith"
What I would like to export is
"SCHEN001","Joe Bloggs Inc",1,1,1,1,1,1,13,6,"Mr John Smith"
Is this possible using Tsql?
Any ideas would be greatly appreciated
Take a look at the bcp.exe utility. It is ment for bulk operations and you can specify templates for exports etc.
A link that seems reasonable: http://www.simple-talk.com/sql/database-administration/creating-csv-files-using-bcp-and-stored-procedures/
Another approach is to use SQL Server Integration Services (if you have MS SQL Server Standard or Enterprise edition)
or, alternatively, you can copy grid results into Excel, and export CSV from there :-)
Try to use this script.
Set variable #TblName to the name of your table.
The script uses information_schema.columns
to get the datatypes for every column in selected table.
DECLARE #TblName varchar(128)
DECLARE #WhereClause varchar(255)
DECLARE #cmd varchar(7000)
SET #TblName = '<YOUR TABLENAME>' --TABLENAME
SET #cmd = ''
create table #tableDef (id int identity (1,1), ColType int, ColName varchar(128))
--Fetch table information
insert #tableDef (ColType, ColName)
select case when DATA_TYPE like '%char%' then 1
when DATA_TYPE like '%datetime%' then 2
else 0 end ,
COLUMN_NAME
from information_schema.columns
where TABLE_NAME = #TblName
order by ORDINAL_POSITION
SELECT #cmd = #cmd
+ ' CASE WHEN ' + ColName + ' IS NULL '
+ ' THEN ''NULL'' '
+ ' ELSE '
+ case ColType
when 1 then ''''''''' + ' + ColName + ' + '''''''''
when 2 then ''''''''' + ' + 'CONVERT(VARCHAR(20),' + ColName + ')' + ' + '''''''''
else 'CONVERT(VARCHAR(20),' + ColName + ')' end
+ ' END + '','' + '
from #tableDef
order by id
select #cmd = 'SELECT ' + left(#cmd,len(#cmd)-8) + '+'''' FROM ' + #tblName
exec (#cmd)
drop table #tableDef

How to add variables in Dynamic Sql, not concatenate them?

I have the following dynamic sql statement where I want to add #StartRowIndex + #MaximumRows and subtract 1 from it. I am unclear on where to put the single quotes in the statement. Here it is:
SET #sql = #sql + ' SELECT *
FROM
LicenseInfo
WHERE RowNum
BETWEEN ' + #StartRowIndex + ' AND ' +
'(' + #StartRowIndex + #MaximumRows + ')' - 1
+ ' ORDER BY cnt desc'
Create new variable #EndRowIndex and calculate it before you construct the dynamic sql statement.
Something like:
DECLARE #EndRowIndex int
SET #EndRowIndex = #StartRowIndex + #MaximumRows - 1
SET #sql = #sql + ' SELECT *
FROM
LicenseInfo
WHERE RowNum
BETWEEN ' + #StartRowIndex + ' AND ' + #EndRowIndex
+ ' ORDER BY cnt desc'
You need to cast the int parameters into varchar
SET #sql = #sql + ' SELECT *
FROM
LicenseInfo
WHERE RowNum
BETWEEN ' + #StartRowIndex + ' AND ' +
'(' + CAST(#StartRowIndex as varchar(10)) + CAST(#MaximumRows as varchar(10)) + ') - 1
ORDER BY cnt desc'
Declare a variable, do the calculation and CAST it to varchar when generating the SQL statement
DECLARE #LastRowIndex int
SET #LastRowIndex = #StartRowIndex + #MaximumRows - 1
SET #sql = #sql + '
SELECT *
FROM LicenseInfo
WHERE 1=1
AND RowNum BETWEEN ' + CAST (#StartRowIndex as VarChar) +
' AND ' + CAST (#LastRowIndex as VarChar)
+ ' ORDER BY cnt DESC'
You have to cast in order to let SQL Server concatenate string values, otherwise it will try to convert the nVarChar to number and try to add them as numerics.