Как отбросить свойство IDENTITY столбца в SQL Server 2005

Вы можете разделить вашу строку следующим образом:

string = "John Clark\nDallas\nSystem Engineer\nGlobal Edge\nWage 2\nY\n1\nRobin James\nCleveland\nArchitect\nMaxSys\nWage 3\nY\n0\nJoseph Neils\nLittle Rock\nDB Admin\nTech Sys\nWage 2\nY\n1\n"

string.split("\n").each_slice(7).to_a
#=> [["John Clark", "Dallas", "System Engineer", "Global Edge", "Wage 2", "Y", "1"], ["Robin James", "Cleveland", "Architect", "MaxSys", "Wage 3", "Y", "0"], ["Joseph Neils", "Little Rock", "DB Admin", "Tech Sys", "Wage 2", "Y", "1"]]
9
задан Community 23 May 2017 в 11:44
поделиться

3 ответа

ЕСЛИ Вы просто обрабатываете строки, как Вы описываете, не был бы он быть лучше просто выбрать вершину N значения первичного ключа во временную таблицу как:

CREATE TABLE #KeysToProcess
(
     TempID    int  not null primary key identity(1,1)
    ,YourKey1  int  not null
    ,YourKey2  int  not null
)

INSERT INTO #KeysToProcess (YourKey1,YourKey2)
SELECT TOP n YourKey1,YourKey2  FROM MyTable

Ключи не должны изменяться очень часто (я надеюсь), но другие столбцы могут без вреда выполнению его этот путь.

доберитесь @@ ROWCOUNT вставки, и можно сделать легкий цикл на TempID, где это будет от 1 до @@ ROWCOUNT

и/или

просто соедините #KeysToProcess со своей таблицей MyKeys и быть на пути без потребности копировать все данные.

Это хорошо работает на моем SQL Server 2005, где MyTable. MyKey является столбцом идентификационных данных.

-- Create empty temp table
SELECT *
INTO #TmpMikeMike
FROM (SELECT
      m1.*
      FROM MyTable                 m1
          LEFT OUTER JOIN MyTable  m2 ON m1.MyKey=m2.MyKey
      WHERE 1=0
 ) dt

INSERT INTO #TmpMike
SELECT TOP 1 * FROM MyTable

SELECT * from #TmpMike



Править
ЭТО РАБОТАЕТ без ошибок...

-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM (SELECT
          m1.*
          FROM MyTable                 m1
              LEFT OUTER JOIN MyTable  m2 ON m1.KeyValue=m2.KeyValue
          WHERE 1=0
     ) dt
...
WHILE ...
BEGIN
    ...
    INSERT INTO #Tmp_MyTable
    SELECT TOP (@n) *
    FROM MyTable
    ...

END

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

3
ответ дан 4 December 2019 в 20:25
поделиться

Вы могли попробовать

SET IDENTITY_INSERT #Tmp_MyTable ON 
-- ... do stuff
SET IDENTITY_INSERT #Tmp_MyTable OFF

Это позволит Вам выбирать в #Tmp_MyTable даже при том, что это имеет столбец идентификационных данных.

Но это не будет работать:

-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM MyTable
WHERE 1=0
...
WHILE ...
BEGIN
    ...
    SET IDENTITY_INSERT #Tmp_MyTable ON 

    INSERT INTO #Tmp_MyTable
    SELECT TOP (@n) *
    FROM MyTable

    SET IDENTITY_INSERT #Tmp_MyTable OFF 
    ...    
END

(результаты по ошибке "Явное значение для столбца идентификационных данных в таблице '#Tmp' могут только быть указаны, когда список столбцов используется, и IDENTITY_INSERT идет".)

Кажется, что нет никакого пути, на самом деле не отбрасывая столбец - но это изменило бы порядок столбцов как упомянутая OP. Ужасный взлом: Составьте новую таблицу на основе #Tmp_MyTable...

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

Вы могли использовать следующий код:

select t.name as tablename, typ.name as typename, c.*
from sys.columns c inner join
     sys.tables t on c.object_id = t.[object_id] inner join
     sys.types typ on c.system_type_id = typ.system_type_id
order by t.name, c.column_id

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

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

7
ответ дан 4 December 2019 в 20:25
поделиться

РЕДАКТИРОВАНИЕ, Переключающее IDENTITY_INSERT, как предложено Daren, является, конечно, более изящным подходом, в моем случае я должен был устранить столбец идентификационных данных так, чтобы я мог повторно вставить выбранные данные в исходную таблицу

Способ, которым я обратился к этому, состоял в том, чтобы составить временную таблицу, как Вы делаете, явно отбрасываете столбец идентификационных данных и затем динамично создаете sql так, чтобы у меня был список столбцов, который исключает столбец идентификационных данных (как в Вашем случае, таким образом, proc все еще работал бы, если бы были изменения в схеме), и затем выполнитесь, sql вот образец

declare @ret int
Select * into #sometemp from sometable
Where
id = @SomeVariable

Alter Table #sometemp Drop column SomeIdentity 

Select @SelectList = ''
Select @SelectList = @SelectList 
+ Coalesce( '[' + Column_name + ']' + ', ' ,'')
from information_schema.columns
where table_name = 'sometable'
and Column_Name <> 'SomeIdentity'

Set @SelectList = 'Insert into sometable (' 
+ Left(@SelectList, Len(@SelectList) -1) + ')'
Set @SelectList = @SelectList 
+ ' Select * from #sometemp '
exec @ret  =  sp_executesql  @selectlist
1
ответ дан 4 December 2019 в 20:25
поделиться
Другие вопросы по тегам:

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