Принуждение типа данных в MS Access сделать запрос таблицы

У меня есть запрос в MS Access, который создает таблицу из двух подзапросов. Для двух создаваемых столбцов я делю один столбец из первого подзапроса на столбец из второго подзапроса.

Тип данных первого столбца — двойной; тип данных второго столбца - десятичный, с масштабом 2, но я хочу, чтобы второй столбец также был двойным.

Есть ли способ принудительно указать тип данных при создании таблицы с помощью стандартного запроса доступа к таблице?


person Alistair Knock    schedule 08.12.2009    source источник
comment
Можете ли вы опубликовать оператор SQL, пожалуйста? Исходное утверждение повлияет на то, как мы ответим.   -  person Rap    schedule 08.12.2009


Ответы (6)


Один из способов сделать это — явно создать таблицу, прежде чем что-либо в нее помещать.

Ваше текущее утверждение, вероятно, выглядит так:

SELECT Persons.LastName,Orders.OrderNo
INTO Persons_Order_Backup
FROM Persons
INNER JOIN Orders
ON Persons.P_Id=Orders.P_Id
WHERE FirstName = 'Alistair'

Но вы также можете сделать это:

----Create NewTable
CREATE TABLE NewTable(FirstName VARCHAR(100), LastName VARCHAR(100), Total DOUBLE)
----INSERT INTO NewTableusing SELECT
INSERT INTO NewTable(FirstName, LastName, Total)
SELECT FirstName, LastName, 
FROM Person p
INNER JOIN Orders o
ON p.P_Id = o.P_Id
WHERE p.FirstName = 'Alistair'

Таким образом, у вас есть полный контроль над типами столбцов. Вы всегда можете удалить таблицу позже, если вам нужно ее воссоздать.

person Rap    schedule 08.12.2009
comment
Я думаю, что это единственный способ сделать это, кроме изменения типов данных после запуска MakeTable. - person David-W-Fenton; 09.12.2009

Вы можете использовать приведение к FLOAT функции CDBL(), но, как ни странно, механизм базы данных Access не может обрабатывать значение NULL, поэтому вы должны обрабатывать это самостоятельно, например.

SELECT first_column, 
       IIF(second_column IS NULL, NULL, CDBL(second_column)) 
          AS second_column_as_float
  INTO Table666
  FROM MyTest;

... но вам понадобится ALTER TABLE, чтобы добавить свои ключи, ограничения и т. д. Лучше сначала просто CREATE TABLE, а затем использовать INSERT INTO..SELECT для его заполнения.

person onedaywhen    schedule 08.12.2009

Вы можете использовать CDbl вокруг столбцов.

person Adriaan Stander    schedule 08.12.2009
comment
Разве @onedayone не прав, что CDbl() не будет обрабатывать Nulls, поэтому вам нужно справиться с этим, как он предложил? - person David-W-Fenton; 09.12.2009
comment
Тогда вы могли бы использовать NZ, а не только iif. Так что используйте CDbl(NZ(ColVal,0)) - person Adriaan Stander; 09.12.2009
comment
Nz() уступает моей конструкции IIF(..IS NULL..): она вызывает синтаксическую ошибку при использовании вне пользовательского интерфейса Access. Кроме того, типизация данных становится странной, потому что Nz() в коде SQL приводит результат к тексту. Дополнительные сведения см. на странице allenbrowne.com/QueryPerfIssue.html. В этом случае, однако, включение его в функцию CDBL() «просто» создает проблему с производительностью. - person onedaywhen; 09.12.2009
comment
@ Дэвид В. Фентон: если вы действительно верите, что @onedayкогда будет правильным, почему вы не проголосовали за ответ? Это ваша общественная обязанность :) - person onedaywhen; 09.12.2009
comment
Из вашей ссылки: функция Nz() заменяет Null другим значением (обычно нулем для чисел или строкой нулевой длины для текста). Новое значение представляет собой тип данных Variant, и VBA помечает его подтипом: String, Long, Double, Date или что-то еще. - person Adriaan Stander; 09.12.2009
comment
Я не проголосовал за ваш ответ, потому что не считаю его лучшим ответом. Даже использование CDbl не решает всех проблем с запросами MakeTable, так как вам по-прежнему не хватает полного контроля над текстовыми полями и индексацией (и просто попробуйте сделать это с внешним соединением, имеющим все значения Null в любом из полей на стороне внешнего соединения и посмотри, что у тебя получится). Лучшее решение — создать таблицу заранее, и я проголосовал за это. - person David-W-Fenton; 10.12.2009
comment
@onedaywhen: хотя хорошо иметь предостережение о том, что Nz() не работает из-за пределов Access, это действительно второстепенная проблема, когда речь идет о том, чтобы сделать это из внутри Access. - person David-W-Fenton; 10.12.2009
comment
@ Дэвид В. Фентон: зависит от того, что вы подразумеваете под Access. Я не вижу ничего в вопросе, который предполагает, что OP использует что-либо, кроме ядра базы данных Access. - person onedaywhen; 10.12.2009
comment
@astander: ... и далее говорится, что при использовании в SQL движок приводит результат к «тексту». В статье делается вывод о том, что конструкция IIF(..IS NULL..) предпочтительнее функции Nz(). - person onedaywhen; 10.12.2009
comment
Я создал запрос в MS-Access, который кажется мне довольно точным - OP использует пользовательский интерфейс Access для управления данными. Нет упоминания об ASP или PHP или любой другой среде, в которой будет использоваться этот SQL. Итак, ваши предостережения относительно Nz() ценны, но совершенно не связаны с заданным вопросом и, следовательно, не заслуживают моего одобрения. - person David-W-Fenton; 11.12.2009
comment
@ Дэвид В. Фентон: «Я создал запрос в MS-Access» кажется мне довольно определенным - может быть, но у меня сложилось впечатление, что вы обычно видите только то, что хотите видеть. Мне кажется, в данном случае вы слишком экстраполируете. В старые времена, когда Jet был допустимой СУБД для приложения VB, многие разработчики использовали MS Access в качестве «SQL Management Studio» для создания постоянных объектов базы данных: таблиц, FK, VIEW и т. д. Таким образом, они использовали бы такой язык как «создание запросов в MS Access», но использование Nz() было бы ошибкой. - person onedaywhen; 11.12.2009
comment
@David W. Fenton: Вы читали, что Аллен Браун написал о том, что Nz() уступает в коде SQL, даже когда применяется пользовательский интерфейс Access? У меня складывается впечатление, что Nz() действительно подходит только для кода, использующего объектную модель Access, например. VBA в формах. - person onedaywhen; 11.12.2009

Простой способ сделать это — создать пустую таблицу с правильными типами полей, а затем запрос Append-To, и Access автоматически преобразует данные в целевое поле.

person Scott Bainbridge    schedule 13.11.2014

У меня была аналогичная ситуация, но у меня был запрос на создание таблицы, создающий поле с типом данных NUMERIC, которое я хотел сделать коротким текстом.

Что я сделал (и я получил идею от Stack), так это создал таблицу с рассматриваемым полем как Short Text и в то же время создал запрос на удаление для очистки записей. Я думаю, это забавно, что запрос DELETE в доступе не удаляет таблицу, а только записи в ней - я думаю, вам нужно использовать функцию DROP TABLE для этого, чтобы очистить таблицу...

Затем я преобразовал запрос make-table в запрос APPEND, чего никогда раньше не делал... и просто добавил выполнение запроса DELETE в свой процесс.

Спасибо, переполнение стека!

Стив

person Steve R    schedule 31.01.2018

Я добавляю '& ""' к полю, которое я хочу сохранить как текст, и '*1' (как при умножении суммы на 1) к полям, которые я хочу сохранить как числовые.

Кажется, это помогает.

person LateAnswer    schedule 14.09.2018