Searching a table using a user-defined function - sql

I'm trying to write an SQL function that given a name of a game, it will allow me to search the table of games for that particular game and returns all the info about that game.
This is the code for the Games table:
CREATE TABLE Games(
game_id INT IDENTITY PRIMARY KEY,
name VARCHAR(50),
release_date VARCHAR(50),
rating VARCHAR(5),
min_age INT,
development_team_email VARCHAR(50) FOREIGN KEY REFERENCES Development_Teams,
release_conference INT FOREIGN KEY REFERENCES Conferences
)
And here is the what I could come up with when I was trying to write the function:
create function SearchGames(#game_name varchar(50))
returns table
begin
declare #game
Select (*)
From Games
where Games.name = #game_name
return #game
end
I'm getting a lot of syntax errors and I don't know what I'm doing wrong. Any help appreciated.

Use inline table valued function syntax and add schema:
create function dbo.SearchGames(#game_name varchar(50))
returns table
AS
RETURN (Select *
From Games
where Games.name = #game_name);
SqlFiddleDemo
If you use stored procedure you need to use:
CREATE TABLE ...;
INSERT INTO ... EXEC stored_procedure #args;
-- another operation on stored procedure resultset
while with inline table function you just:
SELECT * FROM dbo.SearchGames('aaa') GROUP BY ... HAVING ... ORDER BY;

I wouldn't recommend using a function for this, but rather a stored procedure:
Create Proc spSearchGames (#game_name Varchar (50))
As Begin
Select *
From Games
Where name = #game_name
End
Go
And executing it:
Exec spSearchGames 'YourGameName'

Related

Cannot return a user table type form a function

I just wrote this coe example to return a user type from a function:
CREATE TYPE dbo.ScheduledActivity_TVP AS TABLE
(
Id uniqueidentifier NOT NULL primary key,
AdditionalDataTypeSignature nvarchar(100) not null,
AdditionalDataId uniqueidentifier NOT NULL,
AdmissionId uniqueidentifier NOT NULL
)
GO
CREATE OR ALTER function [dbo].[Fun_GetFollowUpBymonth](#admissionId uniqueidentifier)
returns ScheduledActivity_TVP as
begin
declare #q ScheduledActivity_TVP
insert into #q
select Id,
AdditionalDataTypeSignature,
AdditionalDataId,
AdmissionId
from ScheduledActivities
where #admissionId = ScheduledActivities.AdmissionId;
return #q
GO
And Sql Server tells me that I must declare the scalar variable #q.
What is wrong in the code above?
I don't see why you are using a multi-line table value function here; they are notoriously slow.
Use an inline table value function, which doesn't even need a TYPE:
CREATE OR ALTER FUNCTION [dbo].[Fun_GetFollowUpBymonth] (#admissionId uniqueidentifier)
RETURNS table
AS RETURN
SELECT Id,
AdditionalDataTypeSignature,
AdditionalDataId,
AdmissionId
FROM dbo.ScheduledActivities
WHERE #admissionId = ScheduledActivities.AdmissionId;

Can I insert into multiple related tables in a single statement?

I have two related tables something like this:
CREATE TABLE test.items
(
id INT identity(1,1) PRIMARY KEY,
type VARCHAR(max),
price NUMERIC(6,2)
);
CREATE TABLE test.books
(
id INT PRIMARY KEY REFERENCES test.items(id),
title VARCHAR(max),
author VARCHAR(max)
);
Is it possible to insert into both tables using a single SQL statement?
In PostgreSQL, I can use something like this:
-- PostgreSQL:
WITH item AS (INSERT INTO test.items(type,price) VALUES('book',12.5) RETURNING id)
INSERT INTO test.books(id,title) SELECT id,'Good Omens' FROM item;
but apparently SQL Server limits CTEs to SELECT statements, so that won’t work.
In principle, I could use the OUTPUT clause this way:
-- SQL Server:
INSERT INTO test.items(type, price)
OUTPUT inserted.id, 'Good Omens' INTO test.books(id,title)
VALUES ('book', 12.5);
but this doesn’t work if there’s a foreign key involved, as above.
I know about using variables and procedures, but I wondered whether there is a simple single-statement approach.
You can using dynamic sql as follows. Although its awkward to construct query like this.
CREATE TABLE dbo.items (
id INT identity(1,1) PRIMARY KEY,
type VARCHAR(max),
price NUMERIC(6,2)
);
CREATE TABLE dbo.books (
id INT PRIMARY KEY REFERENCES dbo.items(id),
title VARCHAR(max),
author VARCHAR(max)
);
insert into dbo.books(id,title)
exec ('insert into dbo.items(type,price) output inserted.id,''Good Omen'' VALUES(''book'',12.5)')

"Invalid object name" no matter what I name it

GO
-- Create sproc for returning whether a partner has marked their survey as finished
CREATE PROCEDURE CheckIfFinished
#pid UNIQUEIDENTIFIER,
#sid INT
AS
BEGIN
SELECT COUNT(*) FROM Finished WHERE partner_id=#pid AND survey_id=#sid;
END
GO
gives
Invalid object name 'Finished'.
Same as if I changed Finished to MyDatabaseName.dbo.Finished or dbo.Finished.
Makes no sense.
The full context is
CREATE TABLE Finished (
partner_id UNIQUEIDENTIFIER,
survey_id INT,
PRIMARY KEY (partner_id,survey_id),
FOREIGN KEY (partner_id) REFERENCES Partners(id),
FOREIGN KEY (survey_id) REFERENCES Surveys(id)
);
GO
CREATE PROCEDURE CheckIfFinished
#pid UNIQUEIDENTIFIER,
#sid INT
AS
BEGIN
SELECT COUNT(*) FROM Finished WHERE partner_id=#pid AND survey_id=#sid;
END
GO
CREATE PROCEDURE UpdateFinishValue (#partner_id UNIQUEIDENTIFIER,
#survey_id INT,
#finished TINYINT)
AS
BEGIN
IF (#finished = 1 AND NOT EXISTS (SELECT 1
FROM Finished
WHERE Finished.partner_id=#partner_id AND Finished.survey_id=#survey_id))
INSERT INTO Finished (partner_id,survey_id) VALUES (#survey_id,#partner_id)
ELSE
DELETE FROM Finished WHERE partner_id=#partner_id AND survey_id=#survey_id
END
GO
The DBMS is unable to find this object period.
You can check for the table using this simple query:
select * from sys.sysobjects so
where so.name like N'%Finished%'
and so.xtype = N'U'
Also the most common causes to your problem are:
You are looking in the wrong place (server, DB, Schema...)
You lack permission to look for the object.
You got a case-sensitive collation issue.
The objects don't exists (maybe was not created or rolled back)

Temp Table as Output Parameter in Stored Procedure

I would like to know if it is possible and how to have a temporary table as output parameter in a stored procedure. I know that normal tables can not be modified with UPDATE and are only READONLY tables, so I thought of using temp tables. But I don't understand how to pass them to the stored procedure and how to have them as output:
CREATE TABLE #tableBER (ID INT NOT NULL IDENTITY PRIMARY KEY, VAL INT NOT NULL DEFAULT 0);
CREATE TABLE #tableRL (ID INT NOT NULL IDENTITY PRIMARY KEY, VAL INT NOT NULL DEFAULT 0);
ALTER PROCEDURE [dbo].[getFound]
#ber #tableBER OUTPUT,
#rl #tableRL OUTPUT,
AS
BEGIN
...
UPDATE #ber ... --UPDATE
UPDATE #rl ...
SELECT #ber; -- RETURN THE TWO TABLES
SELECT #rl;
END;
Is it possible to do such thing?Thanks!
A stored procedure may reference and use temporary tables that are created in an outer scope. There's no need to mark them as parameters, just create the tables, call the stored procedure, and then inspect the contents:
create procedure DoStuff
as
insert into #TTT (ID) values (1),(2),(3)
And usage:
create table #TTT(ID int not null)
exec DoStuff
select * from #TTT
Results:
ID
-----------
1
2
3

Add value from foreign key table depending on name

I want to have the following two tables:
CREATE TABLE buildings
(
ID int IDENTITY NOT NULL PRIMARY KEY,
city_ID int NOT NULL REFERENCES(cities),
name char(20) NOT NULL
)
CREATE TABLE cities
(
ID int IDENTITY NOT NULL PRIMARY KEY,
name char(30) NOT NULL
)
INSERT INTO cities (name) VALUES ('Katowice')
Now I need that when I write:
INSERT INTO buildings (city_ID,name) values (1,'bahnhof')
makes the same effect that when I write:
INSERT INTO buildings VALUES ('Katowice','bahnhof')
My purpose is that when I want to add building to a city, I think about city name, not its ID in cities table. But sometimes I remember ID, and then I prefer to use ID. Is it possible without creating a procedure?
I am thinking about appropriate procedure:
CREATE PROCEDURE addbuilding
#city_ID int,
#name char
AS
BEGIN
INSERT INTO buildings (city_ID,name) VALUES (#city_ID,#name)
END
But as we can see above, #city_ID can be only int. Something like union in C++ could be a good solution, but is it possible in SQL?
I'm not sure if SQL procedures support union similarly to C++ as you ask, but my suggestion would be a rather simple one: two procedures.
CREATE PROCEDURE add_building_by_city_id
#city_ID int,
#name char
etc
CREATE PROCEDURE add_building_by_city_name
#city_name char,
#name char
etc
And then you could use whichever one you need. Of course that the second procedure would need a simple SELECT first, to find the city by its name and retrieve its ID.