如何在另一台服务器上获取列的默认定义?

时间:2017-07-13 17:00:30

标签: sql-server tsql

当列的表位于另一台服务器上时,是否有办法获取列的默认定义?

我尝试直接查询import bs4, urlparse, json, requests from os.path import basename as bn links = [] # the relative paths to companies data = {} # company name --> company data base = 'http://data-interview.enigmalabs.org/' def bs(r): # returns a beautifulsoup table object for the table in the page of the relative path return bs4.BeautifulSoup(requests.get(urlparse.urljoin(base, r).encode()).content, 'html.parser').find('table') for i in range(1,11): print 'Collecting page %d' % i # add end-point links links += [a['href'] for a in bs('companies?page=%d' % i).findAll('a')] for link in links: print 'Processing %s' % link name = bn(link) data[name] = {} for row in bs(link).findAll('tr'): desc, cont = row.findAll('td') data[name][desc.text.encode()] = cont.text.encode() print json.dumps(data) ,但却发现diffserver.dbname.sys.default_constraints视图使用sys.default_constraints作为"定义"专栏,这显然不适用于另一台服务器。 (它甚至不能在不同的数据库中工作。)

例如,此查询返回"定义"中的所有NULL。列" diffserver"是与您当前使用的服务器不同的服务器。 (此查询假定链接服务器为diffserver。)

OBJECT_DEFINITION

我想要这样做的原因是只从元数据中查看表的所有列定义,除了默认约束之外,我可以成功地完成所有操作。由于上述问题,我可以得到约束 name ,但不能得到定义。这是完整查询,仅适用于上下文。

select * from diffserver.somedb.sys.default_constraints

是否有另一种方法可以从SQL 2008+中的另一台服务器获取列的默认定义? (我已经在SQL 2008和2012上尝试过了。)

更新: 基于这里的答案,我发现了另一条信息。我这样做的服务器上有十几个数据库。我运行以下查询依次替换每个数据库名称为" dbname"在查询中(IOW,如果diffserver有db1,db2和db3,我运行了三次查询,将db1,db2,db3中的每一个替换为" dbname"在查询中):

SELECT o.name,
       c.column_id AS num,
       c.name AS "column",
       CASE
         WHEN t.name IN ('char','varchar','binary','varbinary')
           THEN t.name + '(' + CASE c.max_length WHEN -1 THEN 'max' ELSE CAST(c.max_length AS varchar) END + ')'
         WHEN t.name = 'datetime2'
           THEN t.name + '(' + CAST(c.scale AS varchar) + ')'
         WHEN t.name IN ('decimal','numeric')
           THEN t.name + '(' + CAST(c.precision AS varchar) + ISNULL(','+CAST(c.scale AS varchar),'') + ')'
         WHEN t.name IN ('float','real')
           THEN CASE WHEN c.precision <= 24 THEN 'real' ELSE 'float' END
         WHEN t.name IN ('nchar','nvarchar')
           THEN t.name + '(' + CASE c.max_length WHEN -1 THEN 'max' ELSE CAST(c.max_length/2 AS varchar) END + ')'
         ELSE
           t.name
       END AS "type",
       CASE c.is_nullable WHEN 1 THEN 'NULL' ELSE 'NOT NULL' END AS nulls,
       ISNULL(dc.definition,'') AS "default",
       CASE c.is_identity WHEN 1 THEN 'YES' ELSE '' END AS ident
  FROM sys.objects o
          INNER JOIN sys.columns c ON o.object_id = c.object_id
          LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id
          LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id
 WHERE o.name = 'sometable'
   AND o.type = 'U'
 ORDER BY o.name,c.column_id

对于除一个数据库之外的每个数据库,该查询在每行的定义列中返回NULL。那个数据库不是我用户的默认数据库。它也不是我在当前服务器上的数据库。那么为什么这个数据库工作(修辞问题)呢?我还没有意识到这一点。 可能是它是服务器上安装的第一个数据库,但这是猜想。 (我相信它是第一个安装的数据库,猜想部分是&#34;第一个&#34;是什么导致它工作。)

所以,如果你碰巧选择了一个&#34;对&#34;数据库,然后使用openquery而不是直接查询似乎工作(正如它为建议的答案之一所做的那样)。但是,至少对我来说,它并不适用于服务器上的任何其他数据库。我只通过反复试验找到了一个数据库,所以它绝对不能作为一般答案。

1 个答案:

答案 0 :(得分:0)

我只是尝试使用openquery,它在另一台服务器上运行查询,它似乎对我有用。

select * 
from openquery(linkedservername, 'SELECT o.name,
       c.column_id AS num,
       c.name AS "column",
       CASE
         WHEN t.name IN (''char'',''varchar'',''binary'',''varbinary'')
           THEN t.name + ''('' + CASE c.max_length WHEN -1 THEN ''max'' ELSE CAST(c.max_length AS varchar) END + '')''
         WHEN t.name = ''datetime2''
           THEN t.name + ''('' + CAST(c.scale AS varchar) + '')''
         WHEN t.name IN (''decimal'',''numeric'')
           THEN t.name + ''('' + CAST(c.precision AS varchar) + ISNULL('',''+CAST(c.scale AS varchar),'''') + '')''
         WHEN t.name IN (''float'',''real'')
           THEN CASE WHEN c.precision <= 24 THEN ''real'' ELSE ''float'' END
         WHEN t.name IN (''nchar'',''nvarchar'')
           THEN t.name + ''('' + CASE c.max_length WHEN -1 THEN ''max'' ELSE CAST(c.max_length/2 AS varchar) END + '')''
         ELSE
           t.name
       END AS "type",
       CASE c.is_nullable WHEN 1 THEN ''NULL'' ELSE ''NOT NULL'' END AS nulls,
       ISNULL(dc.definition,'''') AS "default",
       CASE c.is_identity WHEN 1 THEN ''YES'' ELSE '''' END AS ident
  FROM sys.objects o
          INNER JOIN sys.columns c ON o.object_id = c.object_id
          LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id
          LEFT JOIN sys.default_constraints dc ON c.column_id = dc.parent_column_id
                            and dc.parent_object_id = c.object_id
 WHERE  o.type = ''U''
 and o.name = ''sometable''
 ORDER BY o.name,c.column_id')