Jag är ingen hejjare på varken T-Sql eller dynamisk sql.
Jag använder eventuellt inbyggda funktioner och medtoder som inte är brukligt i vissa sammanhang,
ofta är det en stor nackdel och ibland så kanske det t.o.m. kan vara berikande och skapa nytänkande.
Nu till saken.
Denna dynamiska (på gränsen till hyperaktiva), sql:en har säkert många brister och min fråga är:
Om man nu skall normalisera databasen i partiklar och optimera så det står härliga till så leder
det ju även till att frågorna många gånger blir ruggigt komplexa (rätta mig om jag har fel).
Om jag nu vill presentera data ifrån länkade tabeller i en relationsdatabas efter önskemål,
så kan inte jag komma på någon annan lösning än denna (nedanför i kod-block) för att åstakomma det jag vill.
Skall man istället sammanställa alla sökdata så att det ligger i dubbla tabeller för att underlätta söknigen,
eller skall man skapa temporära tabeller?
Tacksam för en liten redogörelse av detta fenomen.
(Jag fick nämligen bassning i ett annat (dumt ) forum, där av min fråga.)
DECLARE @param1 as varchar(150),@sql as varchar(2000),@mycount as int,@c as int
DECLARE @andor as varchar(3), @curr as varchar(3),@orderby as varchar(20)
SET @c=0
SET @andor = 'OR'
SET @sql = ''
SET @curr='SEK'
SET @orderby = '1,2,3,4,5'
SET @param1 = Replace('Detta är ett test',' ','.')
SET @mycount = (select len(@param1) - len(replace(@param1,'.','')))
WHILE @c <= @mycount
BEGIN
SET @sql = @sql +
'(s.keywords LIKE ''%'+ PARSENAME(@param1, @c+1) +'%'' OR
s.city LIKE ''%'+ PARSENAME(@param1, @c+1) +'%'' OR
s.province LIKE ''%'+ PARSENAME(@param1, @c+1) +'%'' OR
c.cKeywords LIKE ''%'+ PARSENAME(@param1, @c+1) +'%'') '+ @andor +' '
SET @c=@c+1
END
SET @sql = left(@sql,len(@sql)-3)
SET @sql = 'SELECT s.id,min(sp.picid),s.province,s.city,
s.bedsh,s.bedr,s.bathr,s.area,s.dish,s.wash,s.air,
s.ppool,s.smook,c.cNameEN,
min(p.pricew)*r.rate,
max(p.pricew)*r.rate,s.advid
FROM search1 AS s
LEFT JOIN search_pics as sp ON s.id=sp.shid
INNER JOIN countries AS c ON s.country=c.id
INNER JOIN pricecategory as p ON s.id=p.shid
INNER JOIN ratesnew as r ON r.currencyF=p.currency
WHERE r.currencyT='''+ @curr +''' AND s.bedsl>=0 AND s.bedsh<=9999 AND ('+ @sql +')
GROUP BY s.id,s.province,s.city,s.bedsh,s.bedr,s.bathr,s.area,
s.dish,s.wash,s.air,s.ppool,s.smook,c.cNameEN,r.rate,s.advid
ORDER BY '+ @orderby
exec(@sql)
Det är klurigt. Jag skulle inte genererat sql-kod mha en SP, det är så dålig stränghantering där. Hellre med C# eller ASP eller dyl.
Undra om jag inte skulle lägga in alla ord som jag vill matcha (dom i param1) i en @table variabel och gjort en INNER JOIN med LIKE i ON-delen:
...
FROM
search1 AS s
INNER JOIN
@myTable t
ON
s.keywords LIKE '%' + t.word + '%'
OR
s.city LIKE '%' + t.word + '%'
OR
s.province LIKE '%' + t.word + '%'
Vilket skulle funka bra om man vill att det ska vara OR för alla ord i @param1. Man kanske kan returnera antal ordträffar i @myTable och matcha med antal ord i @param1 på något sätt?
Jag har en user function som tar en CSV-sträng och lägger in värdena i en table variabel som jag brukar använda mig av:
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
ALTER FUNCTION parseString
(
@sIds AS VARCHAR(8000)
)
RETURNS @Ret TABLE(IDs INT)
AS
BEGIN
DECLARE @FirstPos INT
DECLARE @FirstPos1 INT
DECLARE @SecondPos INT
IF ( datalength( @sIds ) > 0 )
BEGIN
SET @FirstPos = 1
SELECT @SecondPos = charindex(',', @sIds, @FirstPos)
WHILE ( @SecondPos > 0 )
BEGIN
INSERT INTO @Ret
VALUES( cast( substring( @sIds, @FirstPos, @SecondPos - @FirstPos ) AS INT) )
SET @FirstPos = @SecondPos + 1
SET @SecondPos = charindex( ',', @sIds, @FirstPos )
END
INSERT INTO @Ret
VALUES( cast( right( @sIds, datalength( @sIds ) - @FirstPos + 1 ) AS INT ) )
END
RETURN
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
Har funderat på om man skapar en "Full text index" på en tabell och kör uttryck mot det. Då kan man använda sig av "CONTAINS()" och "FREETEXT()", som jag aldrig har testat men då kan man köra uttryck som:
USE Northwind
SELECT CategoryName
FROM Categories
WHERE CONTAINS(Description, '"sea*" OR "bread*"')
GO
USE Northwind
GO
SELECT CategoryName, Description
FROM Categories
WHERE CONTAINS(Description, 'ISABOUT (spread weight (.8),
sauces weight (.4), relishes weight (.2) )' )
GO
Jag vet dock inte om man kan skicka in själva uttryckssträngen i form av en parameter till en SP. Det ska även gå att "vikta" orden så att vissa ord är värda mer i resultatet (som i ex ovan). Men jag har aldrig testat det här så jag vet inte exakt vilka begränsningarna är. Sry.
Toha detta är guld värt.
Jag hade också tänkt mig att testa att full-text-indexera de kolumnerna som sökningen skall gå igenom men jag är helt newbe där så det får vänta lite.
Kommer titta på det så småning om och återkomma.
Tack!
267 ms totalt · 4 externa anrop · v20260731065814-full.51f67c91