Not able to populate a table from the output of a function - sql-server

I am unable to populate my table from the output of my function. I have three columns in my table namely, EmpId,Dates,EmpName. The columns EmpId and EMpName are static values which are getting populated fine but the column Dates has to be populated through a function. However, when I try to do the same I am getting a syntax error.
Please Find below the query I am using
INSERT INTO Dbo.LeaveDates (EmpId,[Date],EmpName) VALUES(#EmpId,MyDate,#Emp_Name)
Select MyDate from [dbo].[ListDates](CONVERT(CHAR, #FromDate),CONVERT(CHAR, #ToDate))
The error I am getting is also under:
*The name "MyDate" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables.
Column names are not permitted.
*
I have declared all variables in question
What am I doing wrong?

You have to do it this way:
INSERT INTO Dbo.LeaveDates (EmpId,[Date],EmpName)
SELECT #EmpId, MyDate, #Emp_Name
FROM [dbo].[ListDates](CONVERT(CHAR, #FromDate),CONVERT(CHAR, #ToDate))
Your query consists essentially of two separate sql statements. An INSERT INTO:
INSERT INTO Dbo.LeaveDates (EmpId,[Date],EmpName)
VALUES(#EmpId,MyDate,#Emp_Name)
followed by a SELECT:
SELECT MyDate
FROM [dbo].[ListDates](CONVERT(CHAR, #FromDate),CONVERT(CHAR, #ToDate))
INSERT fails because, as the error message clearly states, MyDate is not permitted in this context, i.e. as a separate column name, without being selected from a table.

Related

Need to Add Values to Certain Items

I have a table that I need to add the same values to a whole bunch of items
(in a nut shell if the item doesn't have a UNIT of "CTN" I want to add the same values i have listed to them all)
I thought the following would work but it doesn't :(
Any idea what i am doing wrong ?
INSERT INTO ICUNIT
(UNIT,AUDTDATE,AUDTTIME,AUDTUSER,AUDTORG,CONVERSION)
VALUES ('CTN','20220509','22513927','ADMIN','AU','1')
WHERE ITEMNO In '0','etc','etc','etc'
If I understand correctly you might want to use INSERT INTO ... SELECT from original table with your condition.
INSERT INTO ICUNIT (UNIT,AUDTDATE,AUDTTIME,AUDTUSER,AUDTORG,CONVERSION)
SELECT 'CTN','20220509','22513927','ADMIN','AU','1'
FROM ICUNIT
WHERE ITEMNO In ('0','etc','etc','etc')
The query you needs starts by selecting the filtered items. So it seems something like below is your starting point
select <?> from dbo.ICUNIT as icu where icu.UNIT <> 'CTN' order by ...;
Notice the use of schema name, terminators, and table aliases - all best practices. I will guess that a given "item" can have multiple rows in this table so long as ICUNIT is unique within ITEMNO. Correct? If so, the above query won't work. So let's try slightly more complicated filtering.
select distinct icu.ITEMNO
from dbo.ICUNIT as icu
where not exists (select * from dbo.ICUNIT as ctns
where ctns.ITEMNO = icu.ITEMNO -- correlating the subquery
and ctns.UNIT = 'CTN')
order by ...;
There are other ways to do that above but that is one common way. That query will produce a resultset of all ITEMNO values in your table that do not already have a row where UNIT is "CTN". If you need to filter that for specific ITEMNO values you simply adjust the WHERE clause. If that works correctly, you can use that with your insert statement to then insert the desired rows.
insert into dbo.ICUNIT (...)
select distinct icu.ITEMNO, 'CTN', '20220509', '22513927', 'ADMIN', 'AU', '1'
from ...
;

Column name Arguments in the "With" Statement in SQL Server

From the Microsoft online document (https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15), it mentioned that the "With" statement can have a column name as an argument, and then it says that:
"The list of column names is optional only if distinct names for all resulting columns are supplied in the query definition."
What is "if distinct names for all resulting columns are supplied in the query definition" actually means? I use the "With" statement very often, but I never specify column names in the argument.
I tried to go through the entire document but it appears nowhere have explained this in further detail.
Does anyone know under what situation I need to put specify the column name?
Thanks in advance!
Quite simply, the resultset of the query that defines the CTE must return a set of columns with distinct names. For example, the following will not work:
with cte as (select 1 as x, 2 as x)
select * from cte;
The resultset has 2 columns named "x". In such a case, you MUST supply the column names in the definition of the cte since the query produces a resultset with duplicate names. So you would need to use the form:
with cte(x, y) as (select 1 as x, 2 as x)
select * from cte;
As a general matter, it is a best practice for any resultset to NOT have duplicate column names.

SQL Server Sub query with multiple results

I am attempting to populate an existing bridge table from a table that exists as a template for how items are populated into the bridge table.
I am attempting to do a new insert into the bridge table (dbo.ECN_ChecklistItem) where the list of items from dbo.ECN_ChecklistItem (SELECTed by ECNID (a foreign key ID)) differs from dbo.BusinessUnit_ChecklistItem (SELECTed by BusinessUnit and InUse).
I get a SQL exception stating that "Sub query returned more than 1 value. This is not permitted when the sub query follows follows =, !=, <, <= , >, >= or when the subquery is used as an expression."
I have attempted to modify the query to include an 'in' operator rather than a '=' operator, however that was not successful either. I may have done it incorrectly.
CREATE PROCEDURE checkCurrentChecklistItemsAgainstInUseItems
--Parameters
#ECNID INT, --I need the ECNID to do the search properly.
#BU NVARCHAR(50),
#Date NVARCHAR(10), --This is the date that the checklist item was added to the ECN.
#NewStatus NVarchar(3) --This is based off of the status of the ECN, will either be '?' or 'No'
AS
BEGIN
DECLARE #System NCHAR(6)='SYSTEM'
DECLARE #Message NVARCHAR(50) = 'This value was added by the system automatically.'--Not in use.
SET NOCOUNT ON;
INSERT INTO dbo.ECN_ChecklistItem (ECNID, Required, LogBy, LogDate, Description, CheckName)
VALUES(#ECNID, #NewStatus, #System, #Date, NULL,
(Select ChecklistItem FROM dbo.BusinessUnit_ChecklistItem WHERE BusinessUnit Like #BU
EXCEPT SELECT CheckName FROM dbo.ECN_ChecklistItem WHERE ECNID Like #ECNID))
END
GO
The rest of the Insert Statement is towards a single row. However, the subquery might be returning (or has the possibility of returning) multiple rows. Whenever this situation occurs, SQL Server puts up this.
You might want to examine, by running the subquery separately as a query to find whether multiple rows are being returned even as you "assume" that there will be only row returned.
If it does indeed multiple rows, then you will need to handle that situation separately depending on your logic.
However, if you are sure only one row is being returned, you can always a MAX or MIN or TOP 1 . Although they are inconsequential when a single row is being returned, they will avoid the 'subquery returned mutliple' error.
Edit :
If you indeed want multiple rows to be inserted, replace the Values phrase, with the complete select phrase, with values for all the other fields remaining as fixed values (# ones), and the value for CheckName coming from the select statement. Select #..., #..., #...., .... CheckListItem From .... Where BusinessUnit Like ... Except... and so on.

Save Column Types of Stored Procedure

I have a stored procedure I plan to use for SSRS, which contains over 50 different columns. I have another procedure that executes it, and I plan to insert into a result table, but I need to know the column names before hand. When I try to execute, I get an error which states:
Column name or number of supplied values does not match table definition.
I suspect this is because one of my columns is an incorrect data type. How can I figure out exactly what data type those columns are for creating my table?
My insert statement:
insert into #resultset
exec my_proc
As a quick cheat, you could run the guts of the stored proc as a SQL statement, and change the last SELECT statement into something like:
SELECT TOP 0 columnlist
INTO ResultTable
FROM LastSelectStatement
This would give you both the correct column numbers and datatypes.

Query to compare differences of two columns from two different tables

I am attempting to create a UNION ALL query, on two differently named columns in two different tables.
I would like to take the "MTRL" column in the table USER_EXCEL and compare it against the "short_material_number" column from the IM_EXCEL table. I would then like the query to only return the differences between the two columns. Both columns house material numbers but are named differently (column wise) in the tables.
What I have so far is:
(SELECT [MTRL] FROM dbo.USER_EXCEL
EXCEPT
SELECT [short_material_number] FROM dbo.IM_Excel)
UNION ALL
(SELECT [short_material_number] FROM dbo.IM_Excel
EXCEPT
SELECT [MTRL] FROM dbo.USER_EXCEL)
However, when trying to run that query I receive an error message that states:
Msg 8114, Level 16, State 5, Line 22
Error converting data type varchar to float.
You're almost certainly getting this error because one of your two columns is a FLOAT data type, while the other is VARCHAR. This article would be a good place to start reading about implicit conversions, which happen when you try to compare two columns that are of different data types.
To get this working, you need to convert the float to a varchar, like in the example below.
(
SELECT [MTRL] FROM dbo.USER_EXCEL
EXCEPT
SELECT CAST([short_material_number] AS VARCHAR(18)) FROM dbo.IM_Excel
)
UNION ALL
(
SELECT CAST([short_material_number] AS VARCHAR(18)) FROM dbo.IM_Excel
EXCEPT
SELECT [MTRL] FROM dbo.USER_EXCEL
)
From you question I understand you are trying to compare two columns but returning only one column I would recommend you to use following query to compare the differences side by side
SELECT ue.[MTRL], ie.[short_material_number]
FROM dbo.IM_Excel ie
FULL OUTER JOIN
dbo.USER_EXCEL ue
ON CAST(ie.[short_material_number] AS VARCHAR(20)) = ue.[MTRL]
WHERE ie.[short_material_number] IS NULL
OR ue.[MTRL] IS NULL

Resources