@@ -342,55 +342,9 @@ def column_definitions(table_name)
342342 database = identifier . fully_qualified_database_quoted
343343 view_exists = view_exists? ( table_name )
344344 view_tblnm = view_table_name ( table_name ) if view_exists
345- sql = %{
346- SELECT DISTINCT
347- #{ lowercase_schema_reflection_sql ( 'columns.TABLE_NAME' ) } AS table_name,
348- #{ lowercase_schema_reflection_sql ( 'columns.COLUMN_NAME' ) } AS name,
349- columns.DATA_TYPE AS type,
350- columns.COLUMN_DEFAULT AS default_value,
351- columns.NUMERIC_SCALE AS numeric_scale,
352- columns.NUMERIC_PRECISION AS numeric_precision,
353- columns.DATETIME_PRECISION AS datetime_precision,
354- columns.COLLATION_NAME AS [collation],
355- columns.ordinal_position,
356- CASE
357- WHEN columns.DATA_TYPE IN ('nchar','nvarchar','char','varchar') THEN columns.CHARACTER_MAXIMUM_LENGTH
358- ELSE COL_LENGTH('#{ database } .'+columns.TABLE_SCHEMA+'.'+columns.TABLE_NAME, columns.COLUMN_NAME)
359- END AS [length],
360- CASE
361- WHEN columns.IS_NULLABLE = 'YES' THEN 1
362- ELSE NULL
363- END AS [is_nullable],
364- CASE
365- WHEN KCU.COLUMN_NAME IS NOT NULL AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY' THEN 1
366- ELSE NULL
367- END AS [is_primary],
368- c.is_identity AS [is_identity]
369- FROM #{ database } .INFORMATION_SCHEMA.COLUMNS columns
370- LEFT OUTER JOIN #{ database } .INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
371- ON TC.TABLE_NAME = columns.TABLE_NAME
372- AND TC.TABLE_SCHEMA = columns.TABLE_SCHEMA
373- AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
374- LEFT OUTER JOIN #{ database } .INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
375- ON KCU.COLUMN_NAME = columns.COLUMN_NAME
376- AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
377- AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
378- AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
379- INNER JOIN #{ database } .sys.schemas AS s
380- ON s.name = columns.TABLE_SCHEMA
381- AND s.schema_id = s.schema_id
382- INNER JOIN #{ database } .sys.objects AS o
383- ON s.schema_id = o.schema_id
384- AND o.is_ms_shipped = 0
385- AND o.type IN ('U', 'V')
386- AND o.name = columns.TABLE_NAME
387- INNER JOIN #{ database } .sys.columns AS c
388- ON o.object_id = c.object_id
389- AND c.name = columns.COLUMN_NAME
390- WHERE columns.TABLE_NAME = #{ prepared_statements ? '@0' : quote ( identifier . object ) }
391- AND columns.TABLE_SCHEMA = #{ identifier . schema . blank? ? 'schema_name()' : ( prepared_statements ? '@1' : quote ( identifier . schema ) ) }
392- ORDER BY columns.ordinal_position
393- } . gsub ( /[ \t \r \n ]+/ , ' ' ) . strip
345+
346+ sql = column_definitions_sql ( database , identifier )
347+
394348 binds = [ ]
395349 nv128 = SQLServer ::Type ::UnicodeVarchar . new limit : 128
396350 binds << Relation ::QueryAttribute . new ( 'TABLE_NAME' , identifier . object , nv128 )
@@ -457,6 +411,73 @@ def column_definitions(table_name)
457411 end
458412 end
459413
414+ def column_definitions_sql ( database , identifier )
415+ object_name = prepared_statements ? '@0' : quote ( identifier . object )
416+ schema_name = if identifier . schema . blank?
417+ 'schema_name()'
418+ else
419+ prepared_statements ? '@1' : quote ( identifier . schema )
420+ end
421+
422+ %{
423+ SELECT
424+ #{ lowercase_schema_reflection_sql ( 'o.name' ) } AS [table_name],
425+ #{ lowercase_schema_reflection_sql ( 'c.name' ) } AS [name],
426+ t.name AS [type],
427+ d.definition AS [default_value],
428+ CASE
429+ WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint')
430+ THEN c.scale
431+ END AS [numeric_scale],
432+ CASE
433+ WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint', 'real', 'float')
434+ THEN c.precision
435+ END AS [numeric_precision],
436+ CASE
437+ WHEN t.name IN ('date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time')
438+ THEN c.scale
439+ END AS [datetime_precision],
440+ c.collation_name AS [collation],
441+ ROW_NUMBER() OVER (ORDER BY c.column_id) AS [ordinal_position],
442+ CASE
443+ WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length > 0
444+ THEN c.max_length / 2
445+ ELSE c.max_length
446+ END AS [length],
447+ CASE c.is_nullable
448+ WHEN 1
449+ THEN 1
450+ END AS [is_nullable],
451+ CASE
452+ WHEN ic.object_id IS NOT NULL
453+ THEN 1
454+ END AS [is_primary],
455+ c.is_identity AS [is_identity]
456+ FROM #{ database } .sys.columns c
457+ INNER JOIN #{ database } .sys.objects o
458+ ON c.object_id = o.object_id
459+ INNER JOIN #{ database } .sys.schemas s
460+ ON o.schema_id = s.schema_id
461+ INNER JOIN #{ database } .sys.types t
462+ ON c.system_type_id = t.system_type_id
463+ AND c.user_type_id = t.user_type_id
464+ LEFT OUTER JOIN #{ database } .sys.default_constraints d
465+ ON c.object_id = d.parent_object_id
466+ AND c.default_object_id = d.object_id
467+ LEFT OUTER JOIN #{ database } .sys.key_constraints k
468+ ON c.object_id = k.parent_object_id
469+ LEFT OUTER JOIN #{ database } .sys.index_columns ic
470+ ON k.parent_object_id = ic.object_id
471+ AND k.unique_index_id = ic.index_id
472+ AND c.column_id = ic.column_id
473+ WHERE
474+ o.name = #{ object_name }
475+ AND s.name = #{ schema_name }
476+ ORDER BY
477+ c.column_id
478+ } . gsub ( /[ \t \r \n ]+/ , ' ' ) . strip
479+ end
480+
460481 def remove_check_constraints ( table_name , column_name )
461482 constraints = select_values "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{ quote_string ( table_name ) } ' and COLUMN_NAME = '#{ quote_string ( column_name ) } '" , 'SCHEMA'
462483 constraints . each do |constraint |
0 commit comments