variable that can hold a multiple values in sql - sql-server-2008

i am facing a slite problem in sql server 2008 and here is the situation
IF #PatCntFamNbr is not null
BEGIN
select t.Cntid AS Center , t.PatFName AS FirstName , t.PatMName AS MiddleName , t.PatLName AS LastName
from tblpatient t INNER JOIN TblPatientCentres p
ON p.PatID_fk = t.PatId_PK
where p.CentreID_fk=#cntid and #patid in (select patid_fk from tblpatientcentres where cntfammbnbr=#cntfammbnbr)
END
my major problem is that this must show lots of names that belongs to the same family and the variable #patis is accepting only one variable and this is not allowing the procedure to work properly
i will be really thankful for any help

If you need a variable that can hold multiple values then you should use a Table Variable
IE something like DECLARE #patid TABLE(ID INT)
If you need the variable to be passed in via a client application then research table valued types
However your query doesnt look like it needs either - it just needs fixing...
IF #PatCntFamNbr is not null
BEGIN
select t.Cntid AS Center , t.PatFName AS FirstName , t.PatMName AS MiddleName , t.PatLName AS LastName
from tblpatient t INNER JOIN TblPatientCentres p
ON p.PatID_fk = t.PatId_PK
where p.CentreID_fk=#cntid and p.cntfammbnbr=#cntfammbnbr -- this is all you need
END

Related

Search parameter in stored procedure not functioning

I'm trying to create a stored procedure in SQL Server 2008 that searches the (Chinook, if it helps) database's Track table for tracks that match a (part of) an album title. For example, when the parameter is "rock", I'd like to see all the tracks that are on albums that have titles with "rock" in them someplace.
Hard-coding 'rock' works as expected, but running the procedure from Management Studio with 'rock' as the parameter returns a lot of non-"rock" results.
Here is the script I am using to tinker with my stored procedure:
ALTER PROCEDURE [dbo].[searchTrackAlbumTitle]
#trackAlbumTitle nvarchar
AS
BEGIN
SET NOCOUNT ON;
SELECT Track.TrackId
,Track.Name AS TrackName
,Artist.Name AS ArtistName
,Album.Title AS AlbumTitle
,Track.Composer
,Track.Milliseconds
,Track.Bytes
,MediaType.Name AS TypeName
,Genre.Name AS GenreName
,Track.UnitPrice
FROM Track
LEFT JOIN Album ON Track.AlbumId = Album.AlbumId
LEFT JOIN Artist ON Album.ArtistId = Artist.ArtistId
LEFT JOIN MediaType ON Track.MediaTypeId = MediaType.MediaTypeId
LEFT JOIN Genre ON Track.GenreId = Genre.GenreId
WHERE Album.Title LIKE ( '%' + #trackAlbumTitle + '%' ) -- doesn't work
--WHERE Album.Title LIKE ( '%' + 'rock' + '%' ) -- works
END
Put a length on your parameter. e.g.
#trackAlbumTitle NVARCHAR(255)
Right now it's being truncated to NVARCHAR(1). See this blog post for more info - it applies to NVARCHAR, too.
Also note that if you say WHERE Album.anything the LEFT JOIN becomes an INNER JOIN. So you should either move it to the ON clause or change the join to an explicit INNER JOIN. Right now it's confusing - I don't know which behavior you want (and they are different).
try this:
WHERE Album.Title LIKE ( '%' + rtrim(#trackAlbumTitle) + '%' )

SQL Server Stored Procedure Email verification

I have an ASP.net that requests client's information from stored procedure in SQL Server 2008 based on a client's email address until the # sign. Since the clients often change after 3 months in this small organization, but the email addresses remain the same.
E.g. a client with email address obois_in4#cegepoutaouais.qc.ca finishes his/her contract after 3-4 months and then that email address is assigned to someone else.
Now, here's my question: I want my stored procedure to find the client information, after he/she entered obois_in4 and presses the Search button. The reason I don't want them to enter the whole email is because it's too long, and secondly they can make a mistake while typing, but typing such as obois_in4 isn't a big deal.
I wrote a code that can search a client by name, but again, the clients always change after 3-4 months but the email address remains the same.
ALTER PROCEDURE [dbo].[sp_find_client_information]
-- Add the parameters for the stored procedure here
#client_email varchar (50) = null
AS Declare #numOfRows int BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #numOfRows = COUNT (*)
From helpdesk_clients
Where --change first name and
client_firstName = #client_email or client_lastName = #client_email;
begin
if (#numOfRows = 0)
select #numOfRows;
else if (#numOfRows = 1)
select
client_id,
client_firstName,
client_lastName,
client_work_email,
client_work_phone,
client_work_phone_ext,
client_office,
dept_nom,
client_position
from
helpdesk_clients join departments
on
helpdesk_clients.dept_id = departments.dept_id
where client_firstName like '%'+#client_email+'%';
end
END
The email address always starts with obois followed by an underscore _ then the name of the department information technology as in and then by a digit such as 4 in this case. e.g. obois_in4#cegepoutaouais.qc.ca
I am surprised nobody even bothered looking into this. The best solution is to use Substring() and CharIndex()
With SUBSTRING ( expression ,start , length ) we can truncate the string starting from a position within the string until a specified position within a string. With CHARINDEX ( expressionToFind ,expressionToSearch [ , start_location ] ), we can find the the position of a character within a given string.
substring (work_email, 1, CHARINDEX('#', work_email)-1) = #work_email ensures that a parameter doesn't have to be like shawn.smith#cegepoutaouais.qc.ca, and it's a big hassle for a client to enter his full email like shawn.smith#cegepoutaouais.qc.ca, he will only be required to enter shwan.smith, the script will search for shawn.smith in shawn.smith#cegepoutaouais.qc.ca until the # sign.
e.g.
In the stored procedure, assuming the #work_email is parameter and it's value is 'shawn.smith'
select
client_id,
client_firstName,
client_lastName,
client_work_email,
client_work_phone,
client_work_phone_ext,
client_office,
dept_nom,
client_position
from
helpdesk_clients join departments
on
helpdesk_clients.dept_id = departments.dept_id
where substring (work_email, 1, CHARINDEX('#', work_email)-1) = #work_email;
Will return the all the details mentioned in the Select statement.

SQL Server 2008 How to create multiple tables for each record in a table?

I have a table that contains consultant's first name, last name, skill name, and certification which basically shows if the consultant is certified in their skill. I am trying to create a script that will generate a table for each consultant with two columns (skills, and certification status) some consultants may have more than one skill. I am thinking about the while loop syntax or dynamic sql but have no luck. I have searched the web thoroughly with no luck.
You're probably best going about this a different way. Instead of creating tables for each record in another table, just create one second table that links to the first in a one-to-many relationship.
For example:
Consultant
----------
ConsultantID
Name
Skill
-----
SkillID
SkillName
F_ConsultantID
Instead of your proposed solution, I think you want a junction, or mapping table.
Consultant
- ID
- First_Name
- Etc...
Skill
- ID
- Name
Consultant_Skill
- Consultant_ID
- Skill_ID
The consultant_skill table will allow you to have a many-to-many relationship between consultant and skill.
The answer that worked for me based on the lab question's parameters was:
USE Software
Declare #TableNameVar varchar(1000)
Declare #ConsultantIDVar int, #ConsultantIDMax int
Set #ConsultantIDVar = (Select MIN(ConsultantID) From Consultant)
Set #ConsultantIDMax = (Select MAX(ConsultantID) From Consultant)
While #ConsultantIDVar <= #ConsultantIDMax
Begin
Set #TableNameVar = (Select (ConsultantFName + '_' + ConsultantLName)
From Consultant
Where ConsultantID = #ConsultantIDVar)
Set #TableNameVar = 'Create Table '+ #TableNameVar + ' (SkillDescription varchar(40), Certification bit)'
Exec (#TableNameVar)
Set #ConsultantIDVar = #ConsultantIDVar + 1
End

design a stored procedure with multiple parameters and HAVING LIKE

I' m trying to write a stored procedure that will search a fairly simple database with
a USER table (user_id,name,...)
a USER_TYPE table (user_id,type_id) - multi to multi
a TYPE table (type_id,type_name)
a USER_GAME (user_id,game_id) -multi to multi
a GAME table (game_id,game_name)
A same user can have several games. Now, I want to be able to get the user according to a particular type and also according to a/some particular game(s), so that for example I can get all the user with, say type1, and with the games, say game2 and game5. I think I can get round the problem of several game names by passing them as a string parameter and do some kind of HAVING LIKE condition (I call get_user_spec('type1' , 'game3,game5') for example).
So far I get to that point:
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_user_spec`(
IN inTypeName VARCHAR(50),
IN inGameName VARCHAR(150)
)
BEGIN
PREPARE statement FROM
"SELECT u.user_id,t.type_name,GROUP_CONCAT(g.game_name) AS game
FROM user u
INNER JOIN user_type ut
ON u.user_id=ut.user_id
INNER JOIN type t
ON ut.type_id=t.type_id
LEFT JOIN user_game ug
ON u.user_id=ug.user_id
LEFT JOIN game g
ON ug.game_id=g.game_id
WHERE t.type_name=?
GROUP BY u.user_id
HAVING game LIKE CONCAT('%',?,'%')
ORDER BY u.user_id";
SET #p1=inTypeName;
SET #p2=inGameName;
EXECUTE statement USING #p1,#p2;
END
But my real problem is that if I don't pass any game name, I then want to get all users with type1 (I then call get_user_spec('type1' , NULL). But I am then not getting anything as the procedure sees
HAVING game LIKE CONCAT('%',NULL,'%').
I hope that was clear enough. If anybody has any suggestions to get around that problem, I would be very grateful.
Thank you very much.
Change this line:
EXECUTE statement USING #p1,#p2;
to
EXECUTE statement USING #p1, ifnull(#p2, '');
This will cause the LIKE expression to be just '%%', which means "match everything"

Help with MySQL Coalesce and Stored Procedures

I'm (attempting) to write a MySQL stored procedure that parses a large text file. Part of what this procedure does is check to see if the entities (in this case, government contractors) named in each record are already contained in the db. (This is a follow up to this question.) This is my first stored procedure and so I'm sure I've wondered off the rails here, and I would appreciated any help.
Here's what I have right now (after declaring the variables):
-- try and fetch first organization (a government agency)
SET agency = COALESCE(SELECT org_agency_o_id FROM orgs_agencies WHERE org_agency_code = maj_agency_cat,SELECT min(org_id) FROM orgs WHERE org_name LIKE CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
-- check to see if that worked
IF agency = NULL THEN
INSERT INTO orgs (org_name,org_name_length,org_type,org_sub_types) VALUES (CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)),LENGTH(CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5))),'org','Org,GovernmentEntity,Federal,Agency');
SET agency = LAST_INSERT_ID();
END IF;
-- try and fetch second organization
SET org = COALESCE(SELECT MIN(org_id) FROM orgs WHERE org_name IN (vendorname, vendoralternatename, vendorlegalorganizationname, vendordoingasbusinessname), SELECT MIN(org_alias_org_id) FROM orgs_aliases WHERE org_alias in (endorname, vendoralternatename, vendorlegalorganizationname, vendordoingasbusinessname))
IF org = NULL THEN
INSERT INTO orgs(org_name,org_name_length,org_type,org_sub_types,org_created) VALUES (vendorname,LENGTH(vendorname),'org','org',DATE());
SET org = LAST_INSERT_ID();
END IF
Right now MySQL is throwing an error on the line:
SET agency = COALESCE(SELECT org_agency_o_id FROM orgs_agencies WHERE org_agency_code = maj_agency_cat,SELECT min(org_id) FROM orgs WHERE org_name LIKE CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
'maj_agency_cat' is a variable that I declare at the beginning of the procedure and then is assigned dynamically using a cursor that goes through my staging data. The full stored procedure can be viewed here.
I'm sure I'm missing something basic and would appreciate any help.
Try wrapping another () around the inner SELECT statements in your COALESCE arguments. Otherwise, they are not treated as subqueries to be executed first and the value returned, but as query objects passed into COALESCE, which is not a valid argument type for COALESCE:
SET agency = COALESCE((SELECT ..), (SELECT ..))