Могу ли я выбрать 0 столбцов в SQL Server? - PullRequest
6 голосов
/ 03 июня 2010

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

Легко получить результат SELECT с 0 строками (но со столбцами), например SELECT a = 1 WHERE 1 = 0.

Можно ли получить результат SELECT с 0 столбцами (но со строками)? например. что-то вроде SELECT NO COLUMNS FROM Foo. (Это недопустимый T-SQL.)

Я сталкивался с этим, потому что хотел вставить несколько строк без указания каких-либо данных столбца для какой-либо из них. например (SQL Server 2005)

CREATE TABLE Bar (id INT NOT NULL IDENTITY PRIMARY KEY)
INSERT INTO Bar SELECT NO COLUMNS FROM Foo
-- Invalid column name 'NO'.
-- An explicit value for the identity column in table 'Bar' can only be specified when a column list is used and IDENTITY_INSERT is ON.

Можно вставить одну строку без указания каких-либо данных столбца, например, INSERT INTO Foo DEFAULT VALUES.

Можно запросить количество строк (без извлечения фактических данных столбца из таблицы), например, SELECT COUNT(*) FROM Foo. (Но у этого результирующего набора, конечно, есть столбец.)

Я пробовал что-то вроде

INSERT INTO Bar () SELECT * FROM Foo
  -- Parameters supplied for object 'Bar' which is not a function.
  -- If the parameters are intended as a table hint, a WITH keyword is required.

и

INSERT INTO Bar DEFAULT VALUES SELECT * FROM Foo
  -- which is a standalone INSERT statement followed by a standalone SELECT statement.

Я могу делать то, что мне нужно, по-другому, но очевидное отсутствие последовательности в поддержке вырожденных случаев меня удивляет.

Я прочитал соответствующие разделы BOL и ничего не увидел. Я был удивлен, что тоже ничего не нашел через Google.

Ответы [ 7 ]

6 голосов
/ 04 июня 2010

Это одно существенное ограничение SQL и одна из причин, почему SQL не является реляционно полным.

Как вы, возможно, знаете, Хью Дарвен изобрел имена DUM и DEE для двух отношений нулевой степени. SQL не имеет их эквивалента.

3 голосов
/ 03 июня 2010

Нет, это ограничение SQL.В SQL много бородавок, противоречий и асимметрий.К сожалению, она не является математически точной или полной в отличие от реляционной теории и алгебры, на которые она была вдохновлена ​​и предназначена для работы.

2 голосов
/ 03 июня 2010

Нет, то, что вы просите, невозможно. SQL это язык запросов , и вы ничего не запрашиваете в своем желаемом поведении. Независимо от того, извлекаете ли вы фактические данные таблицы в запросе, это не имеет значения, но вы должны извлечь некоторые данные. В вашем COUNT(*) примере вы (очевидно) получаете счетчик.

Единственный способ сделать именно то, что вам нужно, это запросить количество строк, которые вас интересуют (например, COUNT(1) в желаемом предложении WHERE), а затем выполнить цикл над пустым одиночным оператором вставки, который вы используется в вашем примере для этого количества раз. Нет единственного способа сделать это.

1 голос
/ 04 июня 2010

Нет. Выбор должен иметь хотя бы один столбец.

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

Ах, я думаю, что-то понимаю вашу цель здесь. Вы хотите вставить «строки заполнителей» без фактических значений (в любом столбце), и эти столбцы будут заполнены позднее.

Нет, это невозможно. Даже если бы было вставлено 5 «абсолютно пустых» строк, как бы вы обновили их позже? (если вам не на что ссылаться в предложении WHERE)

Я называю это «мышлением на основе электронных таблиц». SQL - это не электронная таблица, это база данных.

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

1 голос
/ 03 июня 2010

Попробуйте

INSERT INTO Bar SELECT * FROM Foo

вместо

INSERT INTO Bar () SELECT * FROM Foo

Однако тип данных и количество столбцов должны совпадать (на самом деле типы данных должны иметь возможность неявного преобразования)

Или ты этого хочешь?

CREATE TABLE Bar (id INT NOT NULL IDENTITY PRIMARY KEY)
INSERT INTO Bar DEFAULT VALUES

или

CREATE TABLE Sequence2 (ID INT IDENTITY not null PRIMARY KEY,
            Somedate DATETIME DEFAULT GETDATE() not null,
            SomeID INT DEFAULT 0 not null)
GO

INSERT INTO Sequence2 DEFAULT VALUES

См. Также: Как вставить значения в таблицу, содержащую только столбец идентификаторов

0 голосов
/ 04 июня 2010
Declare @count as int
select @count = count(*) from mytable
select @count
create table #test (test int identity)
while @count>0
Begin
insert into #test default values
set @count= @count-1
ENd

select * from #test

Получается ли это, что вам нужно?

0 голосов
/ 03 июня 2010

Если я правильно помню, SELECT NULL FROM table_name; - допустимый синтаксис, но я не помню, считается ли это как наличие нулевого столбца или одного столбца (содержащего NULL для каждой строки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...