SQL Server views and stored procedures - sql-server

I am creating a web app using SQL Server on a private framework. This web app has an orderLines table that should only show the ordersLines of the specific order that is currently opened.
My framework allows to pass views as data objects to tables. So basically I can pass a orderlines view to my table and it shows all the orderlines that are in the db, but the problem is I need only the orderlines of my specific order. I have created a stored procedure that receives orderID as a parameter, but I don't know how to use it instead of a view.
The stored procedure code is below and the view is pretty much the same just without the checking of orderID.
CREATE PROCEDURE [dbo].[astp_Sales_OrdersLinesProductsByID]
(#OrderId INT)
AS
SELECT
ol.OrderID, ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
ol.CUT, ol.CDL, ol.Domain, ol.ProductID, ol.Amount,
p.ProductName, p.Supplier, p.Quantity AS TotalQuantity, p.Price,
ol.PrimKey
FROM
dbo.atbl_Sales_OrdersLines AS ol
INNER JOIN
dbo.atbl_Sales_Products AS p ON ol.ProductID = p.ProductID
WHERE
ol.OrderID = #OrderId
I was thinking that maybe there is a way to add the stored procedure to my view? Because from what I see it's not possible to pass parameters to a view.
Could anyone help me with this?
Thank you

A stored procedure can be called by using EXEC:
EXEC <sp_NameHere> #Parameter = <ParameterValueHere>
In your case:
EXEC [dbo].[astp_Sales_OrdersLinesProductsByID] #OrderId = 1
You cannot SELECT from a stored procedure like you would SELECT from a view or table.
However, I completely agree with SMor (as in: the term "View" means something completely different in SQL). You should reconsider your solution as I assume that the framework you are using will provide a method for building the query and/or filtering the results in a more efficient way.

Related

Create table function SQL Server

I would like to create a function which runs a specific query that will extract any DimPatientID that is listed within the DimTestPatient table. Currently, I use the WHERE clause to exclude the test IDs from my query. I would like a function because I will use the WHERE clause on almost any query that I will run in the future.
SELECT
COUNT(*)
FROM
dbo.DimPatient dp
LEFT JOIN
dbo.FactTreatmentHistory th ON dp.DimPatientID = th.DimPatientID
WHERE
dp.DimPatientID NOT IN (SELECT DimPatientID
FROM dbo.DimTestPatient)
try using STORED PROCEDURE , it also supports parameters which are handy when you want to return a result set in the form of table.
it can utilise whole query , including WHERE clause as well.
for details follow the below link :
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/create-a-stored-procedure?view=sql-server-ver16

how to automate creation of view or synonyms to another database and which to use

I have a database maintained by a program. During updates all stored procedures are wiped out. I create reports using stored procedures so all of my custom stored procedures have to be scripted then reloaded when upgrades are done. Also, during the process of using tools within the software views will be created that link two tables. one being an original table and the other typically being a custom fields table.
I have a new database where I want to create the stored procedures that would remain unchanged during upgrades. That being said I have the following questions. What is the best way to do this.
View to the tables which are in one schema and views to the view which are in another but create it in a way that all the views I create are in one schema giving precedent to the views rather than tables. Create synonyms to the tables and views.
The next question would be how to script this to create the object because there are hundreds of tables and view.
Script 1 would create the synonym or view and script 2 can find all the tables or views. how would I be able to run them together or would I just have to use script 2 to create scripts to run in the second database.
Any suggestions would be great and any help understanding which would be best views or synonyms would be great. I want to learn not just be given the answer and if there is any other ideas to accomplish my goal of separating the stored procedures from the main db would be great.
***Script 1***
create synonym table1 for db1.dbo.table1
***Script 2***
select a.name from sys.tables a
inner join sys.schemas b
on a.schema_id = b.schema_id
where a.type = 'U'
You could generate script:
select
FORMATMESSAGE('CREATE SYNONYM %s FOR db1.%s.%s;', -- here goes template
QUOTENAME(a.name),
QUOTENAME(SCHEMA_NAME(b.[schema_id])),
QUOTENAME(a.name)
) AS query_to_run
from sys.tables a
inner join sys.schemas b
on a.schema_id = b.schema_id
where a.type = 'U';
db<>fiddle demo
Using metadata you could build any kind of script, then copy the result from SSMS grid to query pane and execute it.

How to create a "Ghost Table" in SQL Server based off of other tables?

I need to create a "ghost" table in SQL Server, which doesn't actually exist but is a result set of a SQL Query. Pseudo code is below:
SELECT genTbl_col1, genTblcol2
FROM genTbl;
However, "genTbl" is actually:
SELECT table1.col AS genTbl_col1,
table2.col AS genTbl_col2
FROM table1 INNER JOIN table2 ON (...)
In other words, I need that every time a query is run on the server trying to select from "genTbl", it simply creates a result set from the query and treats it like a real table.
The situation is that I have a software that runs queries on a database. I need to modify it, but I cannot change the software itself, so I need to trick it into thinking it can actually query "genTbl", when it actually doesn't exist but is simply a query of other tables.
To clarify, the query would have to be a sort of procedure, available by default in the database (i.e. every time there is a query for "genTbl").
Use #TMP
SELECT genTbl_col1, genTblcol2
INTO #TMP FROM genTbl;
It exists only in current session. You can also use ##TMP for all sessions.

Is it possible to connect an Access form to a SQL Server view

I'm migrating an Access DB to SQL Server and everything is slowly coming along but Im not sure how to connect the Access forms to the SQL Server views.
So far I have all the tables linked to SQL Server and Im working on migrating the Access queries into views, but Ive got this error, A2SS0069: External variable cannot be converted
which references a form in my Access file:
SELECT TOP 9223372036854775807 WITH TIES
[AcuteHospitals].[NHSN_ID],
[AcuteHospitals].[HospitalName],
[Location_LOV].[Description] AS Location,
Sum([RateTable_CLABData].[clabcount]) AS [Number of CLABSI],
Sum([RateTable_CLABData].[numcldays]) AS [Central Line Days],
[RateTable_CLABData].[CLAB_Mean] AS [National Average]
FROM
(([AcuteHospitals]
LEFT JOIN [RateTable_CLABData]
ON [AcuteHospitals].[NHSN_ID] = [RateTable_CLABData].[orgID])
LEFT JOIN [Location_LOV]
ON [RateTable_CLABData].[loccdc] = [Location_LOV].[CDCLoc])
LEFT JOIN [SummaryYQ_LOV]
ON [RateTable_CLABData].[summaryYQ] = [SummaryYQ_LOV].[StartDate]
WHERE ((([SummaryYQ_LOV].[SummaryYQ]) = forms!YQ_Location.text5 ))
GROUP BY
[AcuteHospitals].[NHSN_ID],
[AcuteHospitals].[HospitalName],
[Location_LOV].[Description],
[RateTable_CLABData].[CLAB_Mean],
[RateTable_CLABData].[loccdc]
HAVING ((([RateTable_CLABData].[loccdc]) NOT LIKE '%ped%'))
ORDER BY [AcuteHospitals].[HospitalName], [RateTable_CLABData].[loccdc]
Its the line WHERE ((([SummaryYQ_LOV].[SummaryYQ]) = forms!YQ_Location.text5 ))
So I need to know if it's possible and how to get this new view to connect with the Access form.
The problem is here
WHERE ((([SummaryYQ_LOV].[SummaryYQ]) = forms!YQ_Location.text5 ))
You cannot convert such Access query into a SQL View, but you can use Stored Procedure instead and pass value from the field forms!YQ_Location.text5 as parameter.
Also, you don't need this TOP 9223372036854775807 WITH TIES it is redundant.
You can't reference the Access form in a SQL View directly. You will need to rethink the logic in this. You could either create a number of Views with the appropriate values hard-coded (inadvisable) or convert the View to a Stored Procedure and pass the value in as a parameter.
For example (assuming the parameter is a string):
create proc s_MyStoredProc
#Location varchar(50)
AS
BEGIN
SELECT
[AcuteHospitals].[NHSN_ID],
[AcuteHospitals].[HospitalName],
[Location_LOV].[Description] AS Location,
Sum([RateTable_CLABData].[clabcount]) AS [Number of CLABSI],
Sum([RateTable_CLABData].[numcldays]) AS [Central Line Days],
[RateTable_CLABData].[CLAB_Mean] AS [National Average]
FROM
(([AcuteHospitals]
LEFT JOIN [RateTable_CLABData]
ON [AcuteHospitals].[NHSN_ID] = [RateTable_CLABData].[orgID])
LEFT JOIN [Location_LOV]
ON [RateTable_CLABData].[loccdc] = [Location_LOV].[CDCLoc])
LEFT JOIN [SummaryYQ_LOV]
ON [RateTable_CLABData].[summaryYQ] = [SummaryYQ_LOV].[StartDate]
WHERE ((([SummaryYQ_LOV].[SummaryYQ]) = #Location ))
GROUP BY
[AcuteHospitals].[NHSN_ID],
[AcuteHospitals].[HospitalName],
[Location_LOV].[Description],
[RateTable_CLABData].[CLAB_Mean],
[RateTable_CLABData].[loccdc]
HAVING ((([RateTable_CLABData].[loccdc]) NOT LIKE '%ped%'))
ORDER BY [AcuteHospitals].[HospitalName], [RateTable_CLABData].[loccdc]
END
Just create the SQL server view, and then from the Access font end link to that view. It is easy, not much work.
As for any parameters? Just remove them from the query and views. You then just open up the report using a where clause from the Access client.
In fact using a Access form or report that is bound to a linked table (or in this case view) is easy, and Access will ONLY pull down the reocrds you specifiy in the "where" clause of the open form or open report command.
SQL Server has an excellent (and free) MS-Access to MS-SQL migration tool. It does a very good job of converting MS-Access queries. I haven't tried converting queries with form parameters, but it is certainly worth a look and you may learn some things as well, especially if you plan to convert other queries. http://www.microsoft.com/sqlserver/en/us/product-info/migration-tool.aspx#oracle.

Is there any way I can execute this SPROC and get the result with Entity Framework?

This SPROC "returns" a table with two columns: Id, Score.
Is it possible to execute this SPROC and include the custom data-type as parameters from within Entity Framework?
ALTER PROCEDURE [presenta].[SearchLpi]
// The presenta.IdTableType is a table with just one column "Id"
#selectedLpis presenta.IdTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
WITH Scores AS(
SELECT
ItemId, SUM(Score) AS Score
FROM [Presenta].[presenta].[LpivScores]
WHERE
ListPropertyItemId IN (
SELECT Id
FROM #selectedLpis
)
GROUP BY
ItemId
)
SELECT
i.Id,
s.Score
FROM
Scores s,
Items i
WHERE
s.ItemId = i.Id
END
If not, is there any other way to get the results of the SPROC and being able to join this result with another LINQ-query?
Here you are better of writing a EF linq query directly against the table. See http://msdn.microsoft.com/en-us/library/bb896341.aspx for an example.
If you must use stored procedures, then there is a way using a table as a return type. You need to create a temporary table with the fields that you return. See: http://blogs.msdn.com/bindeshv/archive/2008/11/20/using-stored-procedures-in-entity-framework.aspx
This is one of the areas where EF 4 will bring a substantial improvement. With EF4, you'll be able to pull in a stored procedure, and if the return value of that sproc doesn't map to a given table, you can easily create a so-called complex type (basically a class) that will hold the stored proc return values.
See some blog posts for samples and more info on that:
Automatic Generation of Stored Procedure Return Types
Using a Stored Procedure in Entity Framework 4
A big step for Stored Procedures in EF4
Getting Started with Entity Framework 4 – Complex Types and Entities
Yet another great new feature to look forward to!
Create DefiningQuery in the Store part of the model with properties corresponding to the result of your stored procedure.
You can make it using XML Editor you like. Devart Entity Developer has design-time support for DefiningQueries.
Then create a function import for the procedure and set the return type to the hand-made entity.
Devart Team
http://www.devart.com/dotconnect
ADO.NET data providers for Oracle, MySQL, PostgreSQL, SQLite with
Entity Framework and LINQ to SQL support

Resources