sql insert into values The multi-part identifier could not be bound - sql

I am trying to run this command which shoulld append 80 rows.. but i get.
Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "Frame.Guid" could not be bound.
INSERT INTO studentrecords(recordGuid, studentGuid, courseGuid, licenseGuid, repeatflag, frameGuid, coredata, framescore, timeinframe, locked, daterefreshed, dateinserted)
VALUES (NEWID(), '25d6e1d9-e5ce-42dd-bd6a-5956ec7cb047', '54dffd58-1af9-44cf-982e-ea0e8930878e', '00000000-1111-1111-0000-000000000000', 0, Frame.Guid, '<flags><flag1>1</flag1> <flag2>1</flag2> <flag3>1</flag3> <flag4>1</flag4> <flag5>1</flag5><flag6>1</flag6></flags><StudentAnswer> <CorrectionHistory></CorrectionHistory> </StudentAnswer>', 0, 55860, 1, GETDATE(), GETDATE())
Select Frame.Guid FROM Frame
WHERE (Frame.Course = '54dffd58-1af9-44cf-982e-ea0e8930878e') AND (Frame.Template <> '7d3a3b40-86e3-43f4-a4ca-039afdd0b7a3')

INSERT INTO studentrecords (
recordGuid, studentGuid, courseGuid, licenseGuid,
repeatflag, frameGuid, coredata,
framescore, timeinframe, locked,
daterefreshed, dateinserted
)
SELECT NEWID(),
'25d6e1d9-e5ce-42dd-bd6a-5956ec7cb047',
'54dffd58-1af9-44cf-982e-ea0e8930878e',
'00000000-1111-1111-0000-000000000000',
0, Frame.Guid, '1 1 1 1 11 ', 0, 55860, 1,
GETDATE(), GETDATE()
FROM Frame
WHERE Frame.Course = '54dffd58-1af9-44cf-982e-ea0e8930878e'
AND Frame.Template <> '7d3a3b40-86e3-43f4-a4ca-039afdd0b7a3';

I can't see how you want the "insert" and "select" queries here to be related -- they're both syntactically complete but not linked in any way. You're expecting "Frame.Guid" in the first query to come from the second query, somehow, but I can't quite get how. In any case, that's all that the error message is saying; it can't tell what you mean by Frame.Guid, exactly.

You're referencing Frame.Guid in the insert statement, but there isn't one defined. I suspect you want to select that value into a variable, then use the variable in the insert statement.
DECLARE #frameGUID GUID
SET #frameGUID = (Select Frame.Guid FROM Frame
WHERE (Frame.Course = '54dffd58-1af9-44cf-982e-ea0e8930878e')
AND (Frame.Template <> '7d3a3b40-86e3-43f4-a4ca-039afdd0b7a3'))
INSERT INTO studentrecords(recordGuid, studentGuid, courseGuid, licenseGuid, repeatflag, frameGuid, coredata, framescore, timeinframe, locked, daterefreshed, dateinserted)
VALUES (
NEWID(),
'25d6e1d9-e5ce-42dd-bd6a-5956ec7cb047',
'54dffd58-1af9-44cf-982e-ea0e8930878e',
'00000000-1111-1111-0000-000000000000',
0,
#frameGUID,
'<flags><flag1>1</flag1> <flag2>1</flag2> <flag3>1</flag3> <flag4>1</flag4> <flag5>1</flag5><flag6>1</flag6></flags><StudentAnswer> <CorrectionHistory></CorrectionHistory> </StudentAnswer>',
0,
55860,
1,
GETDATE(),
GETDATE())

You have two statements there. The INSERT statement has no way of knowing that you want the field Frame.Guid out of the SELECT statement.
You need to refactor it into one statement. You can do that by putting all the constants into the SELECT statement (between SELECT and FROM) and deleting the VALUES clause. Then it will be one statement.

Related

how to group by data based on multiple columns then merge rows with same values in SQL

I have a table as below :
DECLARE #t1 TABLE
(
Country VARCHAR(MAX) NOT NULL,
AccountName VARCHAR(MAX) NOT NULL,
DealReference VARCHAR(MAX),
[Probability 0%] INT,
[Probability 50%] INT,
[Probability 100%] INT
)
INSERT INTO #t1 (Country, AccountName, DealReference, [Probability 0%], [Probability 50%], [Probability 100%]) VALUES
('Austria', 'Tech Data Vienna', 'AT-379871323', 0, 8000, 0),
('Austria', 'Tech Data Vienna', 'AT-379871323', 3000, 0, 0),
('Finland', 'Fly Logictics', 'FN-3897214', 6000, 0, 0),
('Germany', 'Electronics De Gmbh', 'DE-20948332', 4000, 0, 0 ),
('Germany', 'Electronics De Gmbh', 'DE-2174634', 0, 2000, 0 ),
('Norway', 'MK distribution Oslo', 'NE-3539232', 9000, 0, 0),
('Sweden', 'Bio Pharm Stockholm', 'SE-3897214', 2500, 0, 0),
('Sweden', 'Bio Pharm Stockholm', 'SE-3897214', 0, 0, 1000);
select * from #t1 order by 1
I want to transform #t1 into the below result.
Basically I will do group by Country and AccountName and add the Total column at the end.
While doing the group by, I want to merge the DealReference values seperate by a comma.
In case there is one unique value for multiple rows it will catch only one value.
Below is my solution, everything works apart apart the column DealReference I couldn't figure out how to merge the values into one cell.
I'm using SQL Server Management Studio 18.11.1, based on the official documentation and multiple answered threads here I should use STRING_AGG(DealReference, ', ')
But I'm getting this error
'STRING_AGG' is not a recognized built-in function name.
This solution for example from a similar issue works for me but the XML PATH is very slow when I run the query on +100k rows.
any suggestions please what I am doing wrong ?
Thank you very much.

Parsing txt file with substring

I inherited a SQL code from my previous co-worker. The script was working the last time I ran it but it returns an error when I tried it today. Surprisingly the code is working on my colleague's PC. I double-check the SQL server database and we are using the same collation, Latin1_General_CS_AS. I did many tests, changing windows system locale etc however none of them work, the error is this:
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
Msg 207, Level 16, State 1, Line 141
Invalid column name 'Value'.
...
However, I couldn't get it! why it is working on one system and not on another! Does anybody has any idea or alternative solution for the substring part.
DROP TABLE IF EXISTS #VievingLive0
SELECT
ProdDay, -- date
HouseId, -- ID
CAST(SUBSTRING(RowText, 2, CHARINDEX('_', RowText, 2)-2) AS INT) AS ChannelId, -- Channel ID
CASE WHEN LEN(s.Value) = 14 THEN LEFT(s.Value, 2) ELSE STUFF(LEFT(s.Value, LEN(s.Value)-12), 3, 0, '_') END AS Individs, -- list of persons
(LEN(s.Value)-12)/2 AS CntIndiv, -- number of persons watching
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-11,2)*3600+substring(s.Value,LEN(s.Value)-9,2)*60+substring(s.Value,LEN(s.Value)-7,2), CAST(ProdDay AS DATETIME)) AS ViewFrom, -- time from
DATEADD(SECOND, substring(s.Value,LEN(s.Value)-5 ,2)*3600+substring(s.Value,LEN(s.Value)-3,2)*60+substring(s.Value,LEN(s.Value)-1,2)+1, CAST(ProdDay AS DATETIME)) AS ViewTo -- time to
INTO #VievingLive0
FROM #All_TX4_files
CROSS APPLY STRING_SPLIT(SUBSTRING(RowText, PATINDEX('%_[A-Za-z][A-Za-z][A-Za-z0-9]%', SUBSTRING(RowText, 2, LEN(RowText)))+2, LEN(RowText)), '_') AS s -- extracting individual vieiwng statemenets from the row
WHERE LEFT(RowText, 1) = 'V' -- LIVE viewing rows
I am trying to parse this format txt:
H98500410_0
W1941.51
Pab_2467211514110343733611_W2898.81
V100_0_2_210_ab075700080859_ab081100081259_ab081700081959_ab082800083059_ab083400083559_ab110600110959_ab111300111459_ab113500115059_ab115300120259_ab120300120359_ab120400123059_ab123100123559_ab124800125359_ab173200173259_ab191200191359_ab191600191759

how Remove certain character at Front and back of a varchar

I have a customer data such as below
Table= Customer
field= CardNo
Data in CardNo:
%ABC?;9991?
%ABC?;99912?
%ABC?;999123?
%ABC?;888123?
Output i want is
9991
99912
999123
888123
However I want to remove all the "%ABC?;" at the front and "?" at the back, in the entire CardNo field. How I do it? I have tried this with no success:
UPDATE Customer
SET cardno = RIGHT(cardno, LEN(cardno) - 7)
I get an error:
"Return Error
Msg 536, Level 16, State 2, Line 1
Invalid length parameter passed to the RIGHT function.
The statement has been terminated."
What's wrong and how can I fix it?
Try like this...
UPDATE Table1 Set Cid=Replace(Left(Cid,Len(CID)-1),'%ABC?;','') FROM TABLE1
Sql Fiddle Demo
If you don't mean exactly this, you should probably be more clear what your intended result is:
DECLARE #foo VARCHAR(32)
SET #foo = '%ABC?;888123?'
SELECT SUBSTRING(#foo, 7, LEN(#foo) - 7)
Result: 888123
As applied to your code:
UPDATE Customer
SET cardno = SUBSTRING(cardno, 7, LEN(cardno) - 7)
Demo
REPLACE will work well. REPLACE('%ABC?;9991?', '%ABC?', '')
You can chain them together to remove the second ? as well.
Here is a rather brute force way, considering all possibilities for the pattern:
UPDATE Customer
SET cardno = (case when cardno like '[%]ABC[?];%[?]'
then substring(cardno, 6, len(cardno) - 7)
when cardno like '[%]ABC[?];%'
then substring(cardno, 6, len(cardno) - 6)
when cardno like '%[?]'
then substring(cardno, len(cardno) - 1)
else cardno
end)

Dynamic UPDATE statement

I want to create a dynamic update query where I need to set a certain value in a column. But the column name needs to be SELECTed from another table.
I have already the following query:
UPDATE core.TableRes
SET (
SELECT Code FROM core.TableFields
INNER JOIN core.TableXTableFields ON TableXTableFields.FieldID = TableFields.FieldID
INNER JOIN core.TableResRefLinks ON TableResRefLinks.ExtraFieldID = TableXTableFields.ExtraFieldID
WHERE TableResRefLinks.TableResRefLinksID = RefLinks.TableResRefLinksID)
= (
SELECT Value FROM core.TableResRefLinks WHERE TableResRefLinksID = RefLinks.TableResRefLinksID)
FROM core.TableRes
INNER JOIN core.TableResRefLinks RefLinks ON RefLinks.ResourceID = TableRes.ResourceID
INNER JOIN core.TableXTableFields ON TableXTableFields.ExtraFieldID = RefLinks.ExtraFieldID
INNER JOIN core.TableFields ON TableFields.FieldID = TableXTableFields.FieldID
WHERE (EndDate IS NULL OR EndDate > GETDATE()) AND
(
SELECT Code FROM core.TableFields
INNER JOIN core.TableXTableFields ON TableXTableFields.FieldID = TableFields.FieldID
INNER JOIN core.TableResRefLinks ON TableResRefLinks.ExtraFieldID = TableXTableFields.ExtraFieldID
WHERE TableResRefLinks.TableResRefLinksID = RefLinks.TableResRefLinksID)
<>
(
SELECT Value FROM core.TableResRefLinks
WHERE TableResRefLinksID = RefLinks.TableResRefLinksID)
It gives me the following errors:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '('.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '='.
Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'FROM'.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near '<'.
Is there a way to solve this? If I change the complete UPDATE and SET statements and replace them with a SELECT *, I get results.
EDIT
Here are the datatypes
TableFields.Code => nvarchar(100)
TableResRefLinks.Value => sql_variant
And the datatypes of the columns that have as column name TableFields.Code are set as sql_variant
You can't solve this using plain SQL. You would need some kind of scripting to build your statement. For example postgresql has a scripting language called "pgpsql" which allows building dynamic SQL statements. But this clearly depends on the underlying RDBMS.
By the way: this works with SELECT as you are doing simple sub-select.

SQL Sproc Parameters: Setting Default Date value

I am trying to create a Stored Procedure that will be used for a Report and I want the 2 date parameters to have a DEFAULT value of today's date and 1 month prior.
Is the below the proper way to do this? I was reading elsewhere that I should use COALESCE...(SEE HERE)This is a touchy production system so I wanted to double check before I went forward.
CREATE PROCEDURE spCaseNoteReport
-- Add the parameters for the stored procedure here
#ContactStartDate DateTime = null,
#ContactEndDate DateTime = null
AS
IF #ContactStartDate is null
SET #ContactStartDate = dateadd(m,-1, CONVERT(date, GETDATE()))
IF #ContactEndDate is null
SET #ContactEndDate = CONVERT(date, GETDATE())
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT (id.LastName + ', ' + id.FirstName) AS 'MemberName'
,c.ContactDate
,Li.ItemDescription AS 'Location'
,c.PresentAtContact
,c.ContactDetails
,c.InsertUser
,c.TimeSpentUnits
FROM dbo.tblCaseNotes c
inner join dbo.tblIdentificationMap id
on c.PersonID = id.PersonID
left outer join dbo.tblCaseNoteContactLocation L
on c.Casenoteid = L.Casenoteid
inner join dbo.tblCaseNotesMaintItem Li
on L.ContactLocationID = Li.ItemID
WHERE c.ContactDate BETWEEN #ContactStartDate AND #ContactEndDate
ORDER BY MemberName, c.ContactDate, c.InsertUser
END
continued
So when I actually tried to run the CREATE PROCEDURE for this I get the following errors -->
Msg 243, Level 16, State 1, Procedure spCaseNoteReport, Line 12
Type date is not a defined system type.
Msg 243, Level 16, State 1, Procedure spCaseNoteReport, Line 14
Type date is not a defined system type.
Nothing wrong with this approach. I use it myself.
Parameter defaults can only be constants or udfs so the alternative is to use udfs which honestly doesn't really help.
Edit: best way to remove a time component from datetime
DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
See this excellent SO Q+A "Most efficient way in SQL Server to get date from date+time?" (not mine!)