Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Söka på en eller flera specifika ord.

Postades av 2008-08-27 10:26:54 - Fredrik Malmström, i forum sql-server/msde, Tråden har 14 Kommentarer och lästs av 1796 personer

Har ett litet problem här och vet inte riktigt hur jag skall lösa det på bästa möjliga sätt, jag är inte en klippa på SQL men visst kan jag skriva avancerade saker.

Ligger nu med en SP som gör sökningar i multipla tabeller och kolumner. Jag har en avancerad och en enkel sökmetod på ASP sida som anropar då denna SP.

Lösningen jag vill skapa behandlar endast så att säga ett fritext-fält där man nu via att ex skriva in

montering

så hittar den alla poster med montering i. Nu vill man ju givetvis kunna begränsa sökträffarna ytterligare och jag vill kunna hitta samtliga som innehåller ex:

montering AND urologi

Då skall samtliga poster med montering och urologi i sig hittas, sätter jag

montering OR urologi

Så skall samtliga poster med montering eller urologi hittas.


Kan man lösa detta genom att bara använda sig av SPn så att säga, där man skickar in fritext-fältet? Samt har ni några bra exempel på det ??


Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-27 11:32:13 - Niklas Jansson

Jag har postat om detta flera gånger på forumet, du får se om Pelles sökning är up to date. =)

Antingen använder man någon färdig tjänst eller så implementerar man det själv.
Sökning sker i två steg; utsökning och rankning, men för vissa modeller slår man ihop dem, eller utför dem i omvänd ordning.

Den enklaste är att låta ranking avgöras från användaren (säg "senast uppdaterad" eller "artikelnummer"), och bara plocka ut alla som är relevanta. Jag tror att det är det du gör, och att det är det du vill göra.
I så fall förespråkar jag dynamiska sql-satser; något i stil med:

1. Sökning av ett ord sker med S("ord"), där t.ex.
S("ord") = SELECT PageID FROM WordCount WHERE Word = "ord"

2. Får du då in en sträng "A AND B" så får du ta snittet av två sökningar:
S("A AND B") = S("A") INTERSECT S("B")
På samma sätt får du
S("A OR B") = S("A") UNION S("B")

Och mer komplicerade uttryck får du göra en liten parser för, t.ex.
S("(A AND B) OR (C AND D)") = (S("A") INTERSECT S("B")) UNION (S("C") INTERSECT S("D"))

Är du med?
Det är möjligt att du kan ta din SP och koppla köra union etc. på den också.


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-27 11:52:31 - Fredrik Malmström



Att bygga den dynamiska SQL-satsen med ex. ASP eller ASP.NET osv. hade varit enkelt, men i detta fall är jag låst till att bygga den i SQL, vilket jag tycker ökar svårighetsgraden med hänsyn till att kolla upp allt detta med om de har satt in AND eller OR i söksträngen samt att då kunna bygga upp SQL-satsen utifrån det. Om det nu är nödvändigt? Kanske tänker för mycket, och bortser något eller?

I detta fall är dessutom SQL-Servern av modell SQL Server 2000. Visst, jag hade gärna använt en extern tjänst, men i detta fall är det inte möjligt av den orsaken att det är ett intranät som systemet befinner sig.

Då kvarstår att implementera den själv. SPn idag är hyffsat stor, dock egentligen väldigt simpel och ej skriven av mig.


Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-27 12:50:37 - Niklas Jansson

<b>>Om det nu är nödvändigt? Kanske tänker för mycket, och bortser något eller?</b>
Såvida inte databasen själv har stöd för det måste du på något sätt hantera det själv.

Att göra det i SQL är ingenting jag skulle rekommendera. Vad är anledningen till att du inte kan göra det i ASP?
Du kanske kan göra något slags mellansteg i ASP som hanterar själva parsingen och som sen går direkt till en sp?

EDIT: Om det bara återstår att göra det i SP så får principen bli något i stil med
DECLARE @Pos INT, @Mx INT
SET @Pos = 0
SET @Mx = Len(input)
WHILE Pos<Mx
BEGIN
IF SUBSTRING(input, pos, 1) = " "
BEGIN
--nytt ord
END
ELSE
IF SUBSTRING(input, pos, 1) = "("
BEGIN
--Ny grupp
END
END


Exakt parsingkod får du komma på eller hitta själv. Det enklaste här är nog att implementera en FSM, men det är förhållandevis mycket jobb.


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-27 13:16:57 - Fredrik Malmström

Kan ju beskriva systemet och dess upplägg idag.

Systemet bygger på Microsoft DNA där vi kan dela in det i följande:

1. UI som består av asp 3.0 sidor som gör anrop till komponenter.

2. Komponenterna (ett gäng dll-filer, 4 st för varje tabell) är sådana som vi skapar per automatik utifrån SPna och tabellerna i databasen, komponenterna blir väl i stort sett ett DAL. Som returnerar Recordsets.

3. Databasen med dess tabeller och SPs.















Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-27 17:22:10 - Fredrik Malmström

Om jag bygger upp SQL-strängen med SQL, dvs en dynamisk sql-sträng då måste jag ju exekvera den via:

Exec()


... uuuuuursrrrsh


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-28 09:24:06 - Håkan Borneland

... nej nej använd sp_executesql i så fall.

/Håkan


Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-28 10:06:02 - Fredrik Malmström

Okei! :)
Har skapat färdigt spliten och lägger in sök orden i en variabel tabell nu istället.

DECLARE @delimiter char(1)
DECLARE @pos int
DECLARE @item varchar(100)
DECLARE @query varchar(255)
DECLARE @tmp varchar(255)
DECLARE @Table table (item varchar(200) not null)

SET @delimiter = ' '
SET @query = 'uppvärmning vätesyra' + @delimiter
SET @pos = charindex(@delimiter,@query,1)

IF @pos <> 0
	BEGIN
		WHILE @pos <> 0
		 BEGIN
				INSERT INTO @Table Select substring(@query,1,@pos - 1)

				Set @query = substring(@query, @pos + 1, len(@query))
				Set @pos = charindex(@delimiter,@query)				
		 END
	END
ELSE
	BEGIN
		INSERT INTO @Table(item) SELECT @query
	END

	select * from @Table

Hur skulle man kunna använda sig av denna variabel tabell som innehåller sökorden på ett vettigt sätt.. eller måste man verkligen bygga upp fanskapet med dynamisk sql?

Gaarggggh....


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-28 13:43:12 - Niklas Jansson

Vad står tabellen för?
Ska alla ord finnas på en sida, eller är en sida ok om ett ord, vilket som helst, finns?

Om du vill ha något mer komplicerat så är det det som är poängen - det enda vettiga sättet att lösa det är med en riktig parsing.

Det blir lite enklare om du väljer att alla ord ska behandlas lika (antingen motsvarande "AND" mellan alla eller motsvarande "OR" mellan alla). Hur sker själva utsökningen idag?


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-28 13:52:07 - Håkan Borneland

Om du använder SQL Server 2005/2008 kan du skriva spliten så här:

<code>
DECLARE @Table table (item varchar(200) not null);
DECLARE @str varchar(1000);
DECLARE @x xml;

SET @str = 'uppvärmning vätesyra';
SET @x = '<i>' + REPLACE(@str, ' ', '</i><i>') + '</i>';

INSERT INTO @Table SELECT x.i.value('.', 'varchar(200)') AS item
FROM @x.nodes('//i') x(i);

SELECT * FROM @Table;
</code>

/Håkan


Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-28 13:55:56 - Fredrik Malmström

Har nu kommit fram till detta:

Sökningen behöver bara fungera så att om du anger:
uppvärmning syra

Så skall detta motsvara: uppvärmning AND syra

idag använder den endast: columnN LIKE '%@param%' samt ett x antal: columnN = @param OR columnN = NULL.

Har iofs kommit en bit på vägen och det funkar bra på mina LIKE, men nu är det bara att få in resten av allt. :)


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-08-28 13:59:18 - Håkan Borneland

Är det en kolumn i databasen som du vill söka i, eller flera olika?

/Håkan


Svara

Sv: Söka på en eller flera specifika ord.

Postades av 2008-08-28 14:16:51 - Fredrik Malmström

Det är 5 kolumner som fritext sökningen görs på, och det är sql server 2000 som databasserver.

Har nu fått till ett script, skall dock försöka få till det lite bättre.


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-09-02 09:34:22 - Fredrik Malmström

set ANSI_NULLS OFF
set QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[XTR_SokForslagsinfo]
(
	@Fritext_o varchar(255) = null,
	@BesparingFran_o int = null,
	@BesparingTill_o int = null,
	@BoloningFran_o int = null,
	@BeloningTill_o int = null,
	@Sifvklass_o int = null,
	@ObjektIdavdelning_o int = null,
	@Sokunderavdelning_o varchar(20) = null,
	@ObjektIdInstans_o int = null,
	@DatumFran_o datetime = null,
	@DatumTill_o datetime = null,
	@AvslutatDatumFran_o datetime = null,
	@AvslutatDatumTill_o datetime = null,
	@ForslagId_o int = null,
	@Forslagsgivare_o int = null,
	@PerIdLamnatTill_o int = null,
	@PerIdNuvarande_o int = null,
	@Forslagsnamn_o varchar(255) = null,
	@Forslagsstatus_o varchar(20) = null,
	@Sokbeslutsenaste_o varchar(1000) = null,
	@MatchType int = 2
)
AS
BEGIN
	DECLARE @delimiter char(1)
	DECLARE @pos int
	DECLARE @item varchar(100)
	DECLARE @tmp varchar(255)
	DECLARE @Table table (item varchar(200) COLLATE Finnish_Swedish_CI_AS not null)
	DECLARE @Wordcount int

	SET @delimiter = ' '
	SET @Fritext_o = @Fritext_o + @delimiter
	SET @pos = charindex(@delimiter,@Fritext_o,1)

	IF(@MatchType != 2)
		BEGIN
				BEGIN
					WHILE @pos <> 0
					 BEGIN
							INSERT INTO @Table Select substring(@Fritext_o,1,@pos - 1)

							Set @Fritext_o = substring(@Fritext_o, @pos + 1, len(@Fritext_o))
							Set @pos = charindex(@delimiter,@Fritext_o)				
					 END
				END
		END 
	ELSE
		BEGIN
			INSERT INTO @Table(item) SELECT @Fritext_o
		END

	SET @Wordcount = (select count(item) from @Table)


	IF EXISTS(SELECT name FROM tempdb..sysobjects WHERE name like '#ObjektTemp')
		DROP TABLE [#ObjektTemp]
	CREATE TABLE #ObjektTemp (
		OBJ_ID int
		)
	IF ((NOT @ObjektIdavdelning_o=NULL) AND (NOT @Sokunderavdelning_o = null))
		INSERT INTO #ObjektTemp EXECUTE _OBS_HamtaAllaObjektIdBarn @ObjektIdavdelning_o, "FV2_LINJEORG"
	ELSE IF (NOT @ObjektIdavdelning_o=NULL)  
		INSERT INTO #ObjektTemp (OBJ_ID ) VALUES(@ObjektIdavdelning_o)


	select
		fog.FOG_DIARIENUMMER As Diarienummer,
		fog.FOG_ID AS Id,
		fog.FOG_NAMN AS Namn,
		fog.FOG_INLAMNAT_DATUM AS InlamnatDatum,
		fts.FTS_NAMN AS Forslagsstatus,
		fgg.FGG_ANONYM As Anonym
	from
		T_PUP_PERSONUPPGIFTER,
		T_FOG_FORSLAG fog inner join 
			(
				select ifog.FOG_ID, (Count(*) * 1.0 / @Wordcount) as traffpoang
					from T_FOG_FORSLAG ifog 
					inner join @Table tbl on 
						(
							ifog.FOG_NAMN like '%'+ tbl.item +'%' OR
							ifog.FOG_DIARIENUMMER like '%'+ tbl.item +'%' OR
							CONVERT(VARCHAR(8000),ifog.FOG_PROBLEMBESKRIVNING) like '%'+ tbl.item +'%' OR 
							CONVERT(VARCHAR(8000),ifog.FOG_FORSLAG) like '%'+ tbl.item +'%' OR
							CONVERT(VARCHAR(8000),ifog.FOG_FORVANTAT_RESULTAT) like '%'+ tbl.item +'%' 
							-- OR tbl.Item = NULL
						) group by ifog.FOG_ID
			) a on fog.FOG_ID = a.FOG_ID
		inner join 
			T_FGG_FORSLAGSGIVARE fgg on fgg.FOG_ID = fog.FOG_ID
		inner join 
			T_FTS_FORSLAGSSTATUS fts on fts.FTS_ID = fog.FTS_ID
	where 
		fgg.PER_ID = T_PUP_PERSONUPPGIFTER.PER_ID AND
	/* */
		(@BesparingFran_o = null OR FOG_BESPARING_ETT_AR >= @BesparingFran_o) AND
		(@BesparingTill_o = null OR FOG_BESPARING_ETT_AR <= @BesparingTill_o) AND
		(@BoloningFran_o = null OR (
			SELECT 
				MAX(bsd.BSD_BELONING) as beloning 
			FROM 
				T_BSD_BESLUTSDATA As bsd, 
				V_FOG_SENASTEBELONINGSBESLUT as vfog
			WHERE 
				vfog.FOG_ID = fog.FOG_ID AND
				bsd.BST_ID = vfog.BST_ID) >= @BoloningFran_o) AND

		(@BeloningTill_o = null OR  
		(
			SELECT 
				MAX(bsd.BSD_BELONING)  as beloning
			FROM 
				T_BSD_BESLUTSDATA As bsd, 
				V_FOG_SENASTEBELONINGSBESLUT as vfog
			WHERE 
				vfog.FOG_ID = fog.FOG_ID AND
				bsd.BST_ID = vfog.BST_ID
		)  <= @BeloningTill_o) AND

		(@ObjektIdavdelning_o = null OR T_PUP_PERSONUPPGIFTER.OBJ_ID_ORGANISATIONSTILLHORIGHET IN (SELECT OBJ_ID FROM #ObjektTemp)) AND				
		(@ObjektIdInstans_o = null OR OBJ_ID_INSTANS_NUVARANDE = @ObjektIdInstans_o) AND
		(@DatumFran_o = null OR FOG_INLAMNAT_DATUM >= @DatumFran_o) AND
		(@DatumTill_o = null OR datediff(d,FOG_INLAMNAT_DATUM,@DatumTill_o) >= 0) AND
		(@AvslutatDatumFran_o = null OR isnull(FOG_AVSLUTAT_DATUM, '1900-01-01') >= @AvslutatDatumFran_o) AND
		(@AvslutatDatumTill_o = null OR datediff(d,isnull(FOG_AVSLUTAT_DATUM, '2099-01-01'),@AvslutatDatumTill_o) >= 0) AND
		(@ForslagId_o = null OR fog.FOG_DIARIENUMMER = @ForslagId_o) AND
		(@Forslagsgivare_o = null OR @Forslagsgivare_o = T_PUP_PERSONUPPGIFTER.PER_ID) AND
		(@PerIdLamnatTill_o = null OR @PerIdLamnatTill_o = fog.PER_ID_LAMNAT_TILL) AND

		/* nuvarande handläggare måste söka i remisspersonerna om förslaget är på remiss */
		--(@PerIdNuvarande_o = null OR @PerIdNuvarande_o = T_FOG_FORSLAG.PER_ID_NUVARANDE) AND
		(@PerIdNuvarande_o = null OR @PerIdNuvarande_o 
		IN(
			SELECT 
				rem.PER_ID 
			FROM 
				T_REM_REMISS rem 
			WHERE 
				fog.BST_ID_SENASTEBESLUT = rem.BST_ID AND
				rem.REM_HAR_SVARAT != 1
			UNION SELECT
					(
						CASE WHEN 
							(
								BST_ID_SENASTEBESLUT NOT IN
								(
									SELECT 
										BST_ID 
									FROM 
										T_REM_REMISS 
									WHERE 
										T_REM_REMISS.FOG_ID = fog.FOG_ID AND 
										T_REM_REMISS.REM_HAR_SVARAT != 1
								)
							) THEN
								PER_ID_NUVARANDE 
							  END
							)
					)
		)
	/*
	Ovanstående betyder: @perIdNuvarande IN ( (remissperson i alla remisser till forslagets senaste beslut som inte är besvarade) 
							   UNION 
							   (PER_ID_NUVARANDE i forslaget om det senaste beslutet inte har nån obesvarad remiss)
							 )
	*/ AND
			(@Forslagsnamn_o = null OR fog.FOG_NAMN LIKE "%"+ @Forslagsnamn_o+ "%") AND
			(@Forslagsstatus_o = null OR fog.FTS_ID = @Forslagsstatus_o OR
			(@Forslagsstatus_o ='AVSL_SLUTBET' AND (fog.FTS_ID='AVSLUTAT' OR fog.FTS_ID='FÄRDIGBEHANDLAT'))) AND
			(@Sifvklass_o = null OR @Sifvklass_o IN(
					SELECT CONVERT(int,CONVERT(varchar(8),OBJ_DATA)) FROM T_OBJ_OBJEKT, T_BST_BESLUT
						WHERE 
							T_OBJ_OBJEKT.OBJ_ID = T_BST_BESLUT.OBJ_ID_SIFV_KLASS AND
							fog.FOG_ID = T_BST_BESLUT.FOG_ID AND 
							OTY_ID = 'FV2_SIFVKLASS' AND
							T_BST_BESLUT.BST_ID IN (
								SELECT MAX(bst2.BST_ID) FROM T_BST_BESLUT bst2 WHERE T_BST_BESLUT.FOG_ID=bst2.FOG_ID AND bst2.OBJ_ID_SIFV_KLASS<>null)))
		
		AND traffpoang = 1  or @MatchType <> 1
	group by 
		fog.FOG_DIARIENUMMER,
		fog.FOG_ID,
		fog.FOG_NAMN,
		fog.FOG_INLAMNAT_DATUM,
		fts.FTS_NAMN,
		fgg.FGG_ANONYM,
		a.traffpoang
	order by 
		a.traffpoang
END


Detta blev resultatet, det är en förändrad SQL-sats, har inte skrivit allt i den dock.. det funkar bara bra nu så länge "fritexten" inte är tom. Är den tom, ja då brakar helvetet löst. Segar segar segar sig, sen dör den.


Svara

Sv:Söka på en eller flera specifika ord.

Postades av 2008-09-02 13:16:30 - Fredrik Malmström

Nu är den modifierad ytterligare, och jag tycker den verkar funka bara bra förutom när den söker på exakta ord, eller den kanske funkar bra.

Har jag ordet "Brödrost i matsalen." så på

Något ord, alla ord hittar den "Brödrost i matsalen." om jag söker på "matsalen", men inte på Exakt, då måste jag skriva: "matsalen.", men "Brödrost i matsalen" hittas givetvis på sökordet "Brödrost" oavsett om jag använder: Något ord, Alla ord eller Exakt sökning.


Summasumarum är ju då att jag måste stripa bort alla lustiga tecken som:
: . , m.fl. som kan tänka sig komma direkt efter ett ord utan mellanrum för att på så sätt kunna ge en träff på "matsalen" vid en exakt sökning om det visar sig att ordet är det sista i meningen och har en punkt efter sig eller mitt i osv.


Vad tror ni?




Svara

Nyligen

  • 14:24 CBD regelbundet?
  • 14:23 CBD regelbundet?
  • 14:22 Har du märkt några verkliga fördel
  • 09:09 Vill du köpa medicinska tester?
  • 12:47 Vem beviljar assistansen – kommune
  • 14:17 Någon med erfarenhet av hemstädnin
  • 14:14 Bör man använda sig av en båtförme
  • 14:12 Finns det någon intressant hundblo

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 569 615
27 953
271 709
5 685
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies