Существует ли способ циклично выполниться через табличную переменную в TSQL, не используя курсор?

Правильный способ сделать это - создать службу в App1 и привязать к ней службу из App2.

Вот ссылка для справки. https://stuff.mit.edu/afs/sipb/project/android/docs/guide/components/bound-services.html

233
задан Ray Vega 14 September 2008 в 20:18
поделиться

3 ответа

Я действительно не вижу точку, почему необходимо было бы обратиться к страшному использованию cursor. Но вот другая опция при использовании версии 2005/2008 SQL Server
Используйте рекурсию

declare @databases table
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)

--; Insert records into @databases...

--; Recurse through @databases
;with DBs as (
    select * from @databases where DatabaseID = 1
    union all
    select A.* from @databases A 
        inner join DBs B on A.DatabaseID = B.DatabaseID + 1
)
select * from DBs
2
ответ дан 23 November 2019 в 03:31
поделиться

Я хотел бы добавить несколько ссылок в один и тот же файл .XSD/ .WSDL в одном проекте.

Подробно. Сервер находится на Java (WebSphere Application Server/7.0). Клиентская библиотека в c #. Мы используем подход «первый договор».

В Visual Studio 2008 я добавляю ссылку на службу. Но вместо моих оригинальных контрактов WSDL/XSD он извлекает фиктивные XService.wsdl и XService_schema1.xsd и генерирует «не такой уж и удобный для разработчиков» код (с обертками сообщений, xStartSpecified stuff, фиктивные коллекции ArrayOfx...). Так чем же я занимаюсь? Я изменяю Reference.svcmap так, чтобы он включал точно исходные контракты WSDL/XSD и вставлял их откуда они принадлежат. Это нормально, я получаю дружественный код и я счастлив.

Но что если кто-то изменит контракт с сервером? Здесь я не могу просто обновить ссылку на службу. Я должен копировать и вставлять новые контракты в папку «Ссылка на услугу» в любое время, когда контракт был изменен.

Для упрощения процесса изменения контракта необходимо добавить мои исходные файлы WSDL/XSD как ссылки во все папки ссылок на услуги. Просто извлеките новый WSDL/XSD, щелкните правой кнопкой мыши Reference.svcmap > Запустить пользовательский инструмент.

Разве это не достойная особенность?

-121--3740538-

Этот стиль (попытки) модульного тестирования, где вы пытаетесь охватить всю огромную кодовую базу с помощью одного публичного метода, всегда напоминает мне хирургов, стоматологов или гинекологов, которые выполняют сложные операции через небольшие отверстия. Возможно, но нелегко.

Инкапсуляция - это старая концепция в объектно-ориентированном дизайне, но некоторые люди воспринимают её до таких крайностей, что страдает тестируемость. Существует еще один принцип OO, называемый Принцип открытия/закрытия , который намного лучше подходит для проверки. Инкапсуляция по-прежнему ценна, но не за счет расширяемости - на самом деле тестируемость - это действительно еще одно слово для открытого/закрытого принципа .

Я не говорю, что вы должны сделать ваши частные методы общедоступными, но я говорю, что вы должны рассмотреть возможность рефакторинга вашего приложения на составные части - много небольших классов, которые сотрудничают вместо одного большого сценария транзакции . Вы можете подумать, что не имеет смысла делать это для решения для одного поставщика, но сейчас вы страдаете, и это один из способов выхода.

То, что часто происходит при разделении одного метода в сложном API, также обеспечивает большую гибкость. То, что начиналось как разовый проект, может превратиться в библиотеку многократного использования.


Вот некоторые мысли о том, как выполнить рефакторинг для данной проблемы: Каждое приложение ETL должно выполнить по крайней мере эти три шага:

  1. Извлечь данные из источника
  2. Преобразовать данные
  3. Загрузить данные в место назначения

(отсюда и имя ETL ). В качестве начала рефакторинга это даст нам как минимум три класса с различными обязанностями: Экстрактор , Трансформатор и Загрузчик . Теперь, вместо одного большого класса,у вас есть три с более целевыми обязанностями. Ничего грязного в этом и уже немного более проверяемого.

Теперь увеличьте масштаб каждой из этих трех областей и узнайте, где можно разделить обязанности еще больше.

  • По крайней мере, вам потребуется хорошее представление в памяти каждой «строки» исходных данных. Если источником является реляционная база данных, можно использовать ORM, но если нет, то такие классы необходимо смоделировать таким образом, чтобы они правильно защищали инварианты каждой строки (например, если поле не может иметь значения NULL, класс должен гарантировать это, создав исключение, если попытка выполняется с нулевым значением). Такие классы имеют четко определенную цель и могут быть протестированы изолированно.
  • То же самое относится и к адресату: для этого нужна хорошая объектная модель.
  • Если в источнике выполняется расширенная фильтрация на стороне приложения, их можно реализовать с помощью образца проектирования Specification . Они, как правило, также очень проверяемы.
  • Шаг Transform - это место, где происходит много действий, но теперь, когда у вас есть хорошие объектные модели как источника, так и назначения, преобразование может быть выполнено Mappers - снова проверяемые классы.

Если у вас есть много «строк» исходных и целевых данных, вы можете дополнительно разделить их в Mappers для каждой логической «строки» и т.д.

Это никогда не должно стать грязным, и дополнительное преимущество (помимо автоматизированного тестирования) заключается в том, что объектная модель теперь является более гибкой. Если вам когда-либо потребуется написать другой ETL приложения с участием одной из двух сторон, у вас уже есть хотя бы одна треть написанного кода.

-121--1419396-

Вот как я это делаю:

declare @RowNum int, @CustId nchar(5), @Name1 nchar(25)

select @CustId=MAX(USERID) FROM UserIDs     --start with the highest ID
Select @RowNum = Count(*) From UserIDs      --get total number of records
WHILE @RowNum > 0                          --loop until no more records
BEGIN   
    select @Name1 = username1 from UserIDs where USERID= @CustID    --get other info from that row
    print cast(@RowNum as char(12)) + ' ' + @CustId + ' ' + @Name1  --do whatever

    select top 1 @CustId=USERID from UserIDs where USERID < @CustID order by USERID desc--get the next one
    set @RowNum = @RowNum - 1                               --decrease count
END

Нет курсоров, нет временных таблиц, нет дополнительных столбцов. Столбец USERID должен быть уникальным целым числом, как и большинство первичных ключей.

38
ответ дан 23 November 2019 в 03:31
поделиться

Я собираюсь предоставить установленное решение.

insert  @databases (DatabaseID, Name, Server)
select DatabaseID, Name, Server 
From ... (Use whatever query you would have used in the loop or cursor)

Это гораздо быстрее, чем любая цикл техники и легче писать и поддерживать.

2
ответ дан 23 November 2019 в 03:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: