The multi-part identifier could not be bound error when assigning a variable - sql

I have looked at several posts regarding the cause of this error and they all seem to point to aliases not being used to identify columns.
SELECT JM.Job_Number, JM.Project_Manager, JM.Superintendent,
ECL.Employee_Name AS PM_Name, ECL2.Employee_Name AS Supt_Name
FROM SPECTRUM.Spectrum.dbo.JC_JOB_MASTER_MC JM
LEFT OUTER JOIN SPECTRUM.Spectrum.dbo.Z_EMPLOYEE_CODE_LIST ECL
ON LTRIM(RTRIM(JM.Project_Manager)) = LTRIM(RTRIM(ECL.Employee_Code))
LEFT OUTER JOIN SPECTRUM.Spectrum.dbo.Z_EMPLOYEE_CODE_LIST ECL2
ON LTRIM(RTRIM(JM.Superintendent)) = LTRIM(RTRIM(ECL2.Employee_Code))
WHERE JM.Company_Code = 'ABC' AND JM.Status_Code = 'A' AND JM.Job_Number = '29-0018-00'
DECLARE
#test varchar(50) = ''
set #test = JM.Project_Manager
PRINT(#test)
The select portion of this runs fine but once I add in the set #test = JM.Project_Manager line I receive the error. Any ideas?

You should set the variable in the select statement:
DECLARE #test varchar(50) = '';
SELECT #test = JM.Project_Manager
FROM SPECTRUM.Spectrum.dbo.JC_JOB_MASTER_MC JM LEFT JOIN
SPECTRUM.Spectrum.dbo.Z_EMPLOYEE_CODE_LIST ECL
ON LTRIM(RTRIM(JM.Project_Manager)) = LTRIM(RTRIM(ECL.Employee_Code)) LEFT JOIN
SPECTRUM.Spectrum.dbo.Z_EMPLOYEE_CODE_LIST ECL2
ON LTRIM(RTRIM(JM.Superintendent)) = LTRIM(RTRIM(ECL2.Employee_Code))
WHERE JM.Company_Code = 'ABC' AND JM.Status_Code = 'A' AND JM.Job_Number = '29-0018-00';
In a SELECT, you can either assign variables or you can return a result set, but not both. You may want other variables for the other columns.
Your code doesn't work because JM is not defined in a SET statement. There is no connection to the previous SELECT.

You need variable but table variable which can hold multiple Project_Managers. So, this would be :
declare #projectmanager table (
Project_Manager varchar(255) )
insert into #projectmanager (Project_Manager)
select JM.Project_Manager
from . . . <rest part of query >;
select *
from #projectmanager;
For your current attempt JM.Project_Manager is actually missing. SQL Server can't find it as it is actually part of SELECT Statement. and the other thing is that you can't assign value to single variable in this way.

Related

Scalar Variable error using var Table but not Temp Table

I am stumped with this one. I have the following code it works fine up to the point of the last #POC_XLATE in the update statement and then I get the error MUST DECLARE SCALAR VARIABLE.
If I change the table to a temp table the code works fine. I have tried moving the select statement to the end of the code, that didn't work. Hope someone has some suggestion on why it is doing this. Thanks in advance.
declare #POC_XLATE as TABLE(
POC_XLATE_ID int NULL,
TAR_ID int NULL,
POC_USERID varchar(50) NULL,
ACTION_DATE datetime NULL
)
insert into #POC_XLATE(POC_XLATE_ID, TAR_ID, POC_USERID, ACTION_DATE)
select * from POC_XLATE
where POC_XLATE.ACTION_DATE is null
select * from #POC_XLATE
update #POC_XLATE
set ACTION_DATE = TAR_DATA.OPEN_DATE
from TAR_DATA
where #POC_XLATE.TAR_ID = TAR_DATA.TAR_ID
A column alias cannot start with a #. That is the sign for a declared scalar variable. So, use table aliases:
update p
set ACTION_DATE = td.OPEN_DATE
from #POC_XLATE p JOIN
TAR_DATA td
on p.TAR_ID = td.TAR_ID ;
But why you would write the query in two steps?
insert into #POC_XLATE(POC_XLATE_ID, TAR_ID, POC_USERID, ACTION_DATE)
select p.POC_XLATE_ID, p.TAR_ID, p.POC_USERID, td.OPEN_DATE
from POC_XLATE p left join
TAR_DATA td
on p.TAR_ID = td.TAR_ID
where p.ACTION_DATE is null;
One step is much cleaner than two.

How to add where condition in query if one variables is not null

I have a query like this:
SELECT CodicePrenotazione, CodicePersonaFisica, Nome, Cognome,
Data, NomeFile, PathFile
FROM AA_V_H_Referti H
INNER JOIN AA_V_ANAG_PersoneFisiche PF
ON H.CodicePersonaFisica = PF.CodiceFiscale
WHERE PF.CodicePersonale = #CodicePersonale
AND Data >= #DataInizio
AND Data <= #DataFine
This query works, but now I want to add another where clause but only if one variables is not null.
So I have this variables:
DECLARE #TipologiaReferto NVARCHAR(500)
......code to populate this variables
now if this variables is not null I want to add this condition on the query
AND TipologiaReferto LIKE #TipologiaReferto
Do it like this:
AND (TipologiaReferto LIKE #TipologiaReferto OR #TipologiaReferto IS NULL)
How about this:
AND (TipologiaReferto LIKE #TipologiaReferto AND #TipologiaReferto != NULL)
if this does not trigger the required result as it also will not return any data set for TigoloigaReferto = NULL, then you might want to put the condition inside the JOIN statement.
Not sure if this works, but how about:
LEFT JOIN #TipologiaReferto AS TR
ON H.Data = TR.TipologiaReferto

Using IN with LIKE

OK I have a question to which an answer might be simple but im not sure how to do it:
Question:
How do i use IN with LIKE?
Why Not Duplicate:
Well I know if i have multiple strings i can use OR to check. But this is not the case with what i am trying to do.
Question Explaination:
I have an SP with a parameter #path, now i would like to send multiple paths, separated by delimiter, (to avoid calling sp multiple times). I split the string using a custom function which returns a table with splited values.
Now how would i go about using the values from that splited values table to be used with LIKE operator.
What I have done so far:
declare
#path varchar(max) = 'CompanyRules/Billing/IntegrationServices|CompanyRules/Reports/IntegrationServices',
#default_code varchar(max) = '1'
declare #tempTable TABLE(path varchar(max))
INSERT INTO #tempTable (path)
SELECT split from fn_splitby(#path, '|')
select prg.path, prg.default_code, prmd.optional_property_1, prmd.optional_property_2, prmd.optional_property_3, prmd.optional_property_4, prmd.optional_property_5, prmd.optional_property_6
from pdm_rule_group prg, pdi_rule_master prmd
where prg.path = prmd.path
AND prg.path in (select path from #tempTable)
AND prg.default_code != #default_code
The this will not yield any result.
Possible Solution:
What i though was that i have to loop through the #tempTable and then create separate strings to be used with LIKE. Which im sure is a bad solution, and may have some other solution to it.
Replace this statement
AND prg.path in (select path from #tempTable)
with
AND EXISTS (select 1 from #tempTable where prg.path like "%"+path+"%" )
Just join to the table:
select prg.path, prg.default_code, prmd.optional_property_1, prmd.optional_property_2, prmd.optional_property_3, prmd.optional_property_4, prmd.optional_property_5, prmd.optional_property_6
from
pdm_rule_group prg
inner join
pdi_rule_master prmd
on prg.path = prmd.path
inner join
#tempTable tt
on
prg.path like tt.path
where
prg.default_code != #default_code

Pass string into SQL WHERE IN

I am working on a query page where a user selects a value which represents different types, each identified by an ID.
The problem is selecting these IDs from the data base using the WHERE IN method.
This is my SQL statement
SELECT M.REG_NO, T.TYPE_ID
FROM MAIN AS M
INNER JOIN CLASSIFICATION AS C
ON M.REG_NO = C.REG_NO
INNER JOIN TYPE AS T
ON T.TYPE_ID = C.TYPE_ID
WHERE T.TYPE_ID IN (#Types)
it will work for one single value, eg. 46, but NOT if the value is in brackets, eg. (46) or ('46'), the way it should be for the IN.
I am using visual studio which is auto generating the method to access the table adapter to get the values so I think I HAVE to do this through SQL.
I am passing a string, eg. Types = "46,267,2010" , into the adapter method which passes the string into the #Types in the SQL statement.
Any help would be great. Thanks!
This is a pretty common problem -- not sure why TSQL hasn't dealt with it yet. Anyway, the solution I've found works best for me is to convert the variable to a table, and then you can use IN() on it just fine.
Starting with the function:
CREATE Function [dbo].[ParseStringList] (#StringArray nvarchar(max) )
Returns #tbl_string Table (ParsedString nvarchar(max)) As
BEGIN
DECLARE #end Int,
#start Int
SET #stringArray = #StringArray + ','
SET #start=1
SET #end=1
WHILE #end<Len(#StringArray)
BEGIN
SET #end = CharIndex(',', #StringArray, #end)
INSERT INTO #tbl_string
SELECT
Substring(#StringArray, #start, #end-#start)
SET #start=#end+1
SET #end = #end+1
END
RETURN
END
And then to use the function...
SELECT *
FROM table
WHERE SomeFieldValue In (Select ParsedString From dbo.ParseStringList(#Types))
It's because you need to have a set of values separated by commas. Like
WHERE
T.TYPE_ID IN ('46', '45', '44');
Are you usign SQL Server or Oracle, MySQL?
If you have a string composed of your multiple values such as
T.TYPE_ID IN ('46,45,44');
You might need a function that will explode your string usign a delimiter (split or whatever it is called depending on you DBMS)
The following Select working fine for me:
SELECT M.REG_NO, T.TYPE_ID
FROM MAIN AS M
INNER JOIN CLASSIFICATION AS C
ON M.REG_NO = C.REG_NO
INNER JOIN TYPE AS T
ON T.TYPE_ID = C.TYPE_ID
WHERE (','+#Types+',') LIKE '%,' +T.TYPE_ID+ ',%'

Nhibernate formula appending template word to sql keyword

I am using the following formula in my mapping file :
select top 1 SI.ID from Table SI with(nolock) where SI.GUID = GUID And SI.IsArchive = '0'
the genrated sql is :
select top 1 SI.ID from Table SI with(this_.nolock) where SI.GUID = this_.GUID And SI.IsArchive = '0'
The nolock is a keyword. I don't want it to be qualified with this_.(template keyword).
how can I change this behaviour ?
You can try to refactor the formula logic into a user-defined function (assuming this is sql server here) and call that directly from the formula. You could even make the function part of your schema generation by using the database-object mapping.
For example:
CREATE FUNCTION [dbo].[GetMyValue] ( #entityId INT )
RETURNS INT
AS BEGIN
DECLARE #RtnValue AS INT
SELECT #RtnValue = top 1 SI.ID from Table SI with(nolock) where SI.id = #entityId AND SI.IsArchive = '0'
RETURN #RtnValue
END
And map as such
formula="dbo.GetMyValue(id)"
That should, in theory, prevent any sort of keyword replacement from happening.
It may be possible to work around this with query substitutions in your nhibernate config; for example:
<property name="hibernate.query.substitutions">mynolock nolock</property>
And map as such:
select top 1 SI.ID from Table SI with(mynolock) where SI.GUID = GUID And SI.IsArchive = '0'