powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разобрать строку
17 сообщений из 17, страница 1 из 1
Разобрать строку
    #32061368
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите плз.
Есть идея передать в ХП в качестве параметра строку с какаим нибудь разделителем. Так вот вопрос как ее распарсить,т.е найти все ее состовляющие части.
Типа
'123;34;1;......'
Количество знаков между разделителем заранее не известно. Что не могу сообразить как ето сделать внутри ХП.
ЗЫ
Или не парить себе мозги и делать ето на клиенте?
...
Рейтинг: 0 / 0
Разобрать строку
    #32061371
Фотография Fedorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE FUNCTION [dbo].[udf_string_to_table] (@StrValue varchar( 8000 ), @Delimiter varchar( 10 ))
RETURNS @Array TABLE (strValue varchar( 50 ))

AS
BEGIN
DECLARE @StartLoc int, @EndLoc int, @Len int, @Val varchar( 50 ), @ValNum int

IF LEN(@Delimiter) =  0  RETURN

  SELECT @StartLoc =  1 , @EndLoc =  1 , @Len = LEN(@StrValue), @ValNum =  1 
  WHILE @Len >  0  
  BEGIN
    SELECT @EndLoc = CHARINDEX(@Delimiter, @StrValue, @StartLoc)
    IF @EndLoc =  0  SELECT @EndLoc = @Len +  1 , @Len =  0 
     SELECT @Val = LTRIM(SUBSTRING(@StrValue, @StartLoc, @EndLoc - @StartLoc))
       IF @Val <> ''
    BEGIN
       INSERT @Array (strValue) SELECT @Val
    END
    SELECT @StartLoc = @EndLoc + LEN(@Delimiter), @ValNum = @ValNum +  1 
  END
RETURN
END
...
Рейтинг: 0 / 0
Разобрать строку
    #32061373
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061375
Фотография MiCe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CHARINDEX ( expression1 , expression2 [ , start_location ] )
в цикле....
типа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
declare @instr varchar( 50 ),@par varchar( 10 ), 
           @start int,@end int
select @instr='sdfsdf;dfg;wer;wert;ssd',@start= 1 
@end=CHARINDEX(';',@instr,@start)
while @end> 0 
begin
  @par=substring(@instr,@start,@end-@start+ 1 )
   -- или left если не нужно сохранять значение @instr
 
 --- your code
 
  select @start=@end
end
 -- проверить если в конце строки нет разделителя 
 
 -- усли через left то он в ней и остался иначе
 
if len(@instr)>@start select @par=substring(@instr,@start,len(@instr))
...
Рейтинг: 0 / 0
Разобрать строку
    #32061377
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
declare @i int, @str varchar(128)
set @str='1;12;123;1234;12345;123456;'
--советую ставить разделитель и в самом конце
set @i=charindex(';',@str)
while @i>0
begin
print substring(@str,1,@i-1)
set @str=right(@str,len(@str)-@i)
set @i=charindex(';',@str)
end
...
Рейтинг: 0 / 0
Разобрать строку
    #32061432
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то видел такое красивое решение. Суть в том, что разбирать ничего не надо.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table #t(c int)
go

declare @s varchar( 111 )
set @s='123;34;1;0' 

declare @q varchar( 8000 )
select @q='insert #t select '+ replace(@s,';',' union select ')
exec(@q)

select * from #t
...
Рейтинг: 0 / 0
Разобрать строку
    #32061440
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем большое спасибо.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061477
Фотография snake
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не перестаю удивлятся...
...
Рейтинг: 0 / 0
Разобрать строку
    #32061481
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если у вас SQL2000, то могу предложить такой способ

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_ArrayString2Table2]') and OBJECTPROPERTY(id, N'IsProcedure') =  1 )
drop procedure [dbo].[sp_ArrayString2Table2]
GO


CREATE PROCEDURE [dbo].[sp_ArrayString2Table2]
	@instr text=NULL, @rowpattern varchar( 100 ) = '//node'
AS

IF @instr IS NULL
	RETURN - 1 

DECLARE @XMLHandler int

EXEC sp_xml_preparedocument @XMLHandler OUTPUT, @instr  
SELECT * FROM OpenXML(@XMLHandler, @rowpattern,  0 ) WITH (value int '@value')
EXEC sp_xml_removedocument @XMLHandler


go

create table #t(value int)
insert #t exec [dbo].[sp_ArrayString2Table2] '<root><node value="1"></node><node value="2"></node>
<node value="3"></node><node value="4"></node></root>'
select * from #t
drop table #t
go


Преимущество на мой взгляд в том, что можно передавть в процедуру очень большие массивы данных без их дополнительного разбора.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061489
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glory Снимаю шляпу!!!
Но к сожалению 7. Вот скоро перскочим на 2000 ,тогда будем юзать.
Еще раз всем спасибо.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061571
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Glory
ИМХО, при больших массивах данных лучьше на клиенте создать врем. таблицу, заполнить и вызвать ХП. Такой вариант будет создавать нагрузку на сервер в десятки (для больших массивах данных), или в сотни (для малых) раз меньше, чем sp_xml_preparedocument и т.д.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061714
Фотография Fedorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare @s VARCHAR( 4000 )
CREATE TABLE #example (num int)

INSERT into #example VALUES ( 1 )
INSERT into #example VALUES ( 2 )
INSERT into #example VALUES ( 3 )
INSERT into #example VALUES ( 4 )
INSERT into #example VALUES ( 5 )
INSERT into #example VALUES ( 6 )
INSERT into #example VALUES ( 7 )
INSERT into #example VALUES ( 28 )
INSERT into #example VALUES ( 27 )
INSERT into #example VALUES ( 29 )
INSERT into #example VALUES ( 10 )

Set @s= '1,3,5,10,28'
select * from #example
where CHARINDEX(','+CONVERT(VARCHAR,num)+',' , ','+@s+',') <>  0  

DROP TABLE #example
...
Рейтинг: 0 / 0
Разобрать строку
    #32061747
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2alexeyvg
Не знаю, на очень больших не проверял. На паре тысяч все нормально.
...
Рейтинг: 0 / 0
Разобрать строку
    #32061851
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Glory
"На паре тысяч все нормально" - это значит, не медленнее, чем вариант с врем. таблицей или это значит, что визуально быстро?
Я вот делал проверки и вроде-бы такой вариант (через xml) не позволяет достичь хотя-бы десятков разборов в секунду на двухпроцессорном сервере.
Т.о. как основной метод передачи массивов в процедуру это не подходит. Я сам активно использую sp_xml_preparedocument, но только для задачи импорта/экспорта.
Кроме того, Вы знаете, что sp_xml_preparedocument на время своей работы блокирует SQLDMO? И, как я подозреваю, не масштабируется при добавлении процессоров.
...
Рейтинг: 0 / 0
Разобрать строку
    #32062101
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok
Постараюсь сравнить с получением конкретных цифр.
...
Рейтинг: 0 / 0
Разобрать строку
    #32062358
flatron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuper
прикольно, только они не по порядку выдаются :))
...
Рейтинг: 0 / 0
Разобрать строку
    #32065613
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2alexeyvg
Возвращаясь так сказать к нашим баранам, т.е. XML-ям
Условия тестов
1. Клиентское приложение - простейший VB Script
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
Public cnn, cmd, rst, strConn, fso, file, fh
Set cnn	= CreateObject( "ADODB.Connection" )
Set cmd	= CreateObject( "ADODB.Command" )
Set rst	= CreateObject( "ADODB.Recordset" )
Set fso	= CreateObject( "Scripting.FileSystemObject" )
Set file = fso.GetFile( "c:\myxml9.xml" )
Set fh = file.OpenAstextStream( 1 , - 1 )

strConn =  "PROVIDER=MSDASQL;DRIVER={SQL Server};"  & _
	 "SERVER=myserver;"  & _
	 "DATABASE=pubs;"  & _
	 "Trusted_connection=Yes;"  & _
	 "Network=DBMSSOCN;"  & _
	 "UseProcForPrepare=0 ;" & _
	 "AutoTranslate=No" 

With cnn
        .ConnectionString = strConn
        .Open strConn
	.CommandTimeout =  0 
End With

If cnn.State =  1  Then
	WScript.Echo  "Connected" 
	Set cmd.ActiveConnection = cnn
	cmd.CommandText =  "sp_ArrayString2Table2" 
	cmd.CommandType =  4 
	cmd.CommandTimeout =  0 

            
	' Set up an input parameter.
	x = fh.ReadAll()
	cmd.Parameters.Append cmd.CreateParameter( "Input" ,  201 ,  1 , Len(x), x)

	start = Now
	Set rst = cmd.Execute
	WScript.Echo datediff( "s" , start, Now())
	rst.Close
End If
cnn.Close
Set cnn = Nothing
Set cmd = Nothing
Set fso = Nothing
Set file = Nothing
Set fn = Nothing


2. Исходные данные - xml файлы в формате
<root><node value="0000001"/>...</root>

3. Каждый исходный файл обрабатывался 5 раз. выбиралось максимальное время. Как видно из скрипта засекалось время работы процедуры(почти).

4. Сервер
Microsoft SQL Server 2000 - 8.00.679 (Intel X86) Aug 26 2002 15:09:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 3)
2xPIII-733, RAM 2Gb (SQL reserved 1,7)

Результаты
Код: plaintext
1.
2.
3.
4.
5.
6.
Кол-во записей    Время, сек
 50   000                 3 
 100   000                5 
 200   000                10 
 300   000                16 
 500   000                34 
 900   000                88 


Загрузка процессоров колебалась от 25 до 50% (начиная с 200 000) и была симметрично распределена на оба процессора.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разобрать строку
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]