我们可以在Select Query中的From Clause中执行动态SQL吗?

时间:2016-06-22 03:58:32

标签: sql sql-server

from子句中的select查询是否可以是动态sql? 例如

DECLARE @sql NVARCHAR(MAX)
SET @sql='SELECT * table'

SELECT t.*, a+b AS total_sum
FROM
(
   EXEC (@sql)
) t

如果无法实现上述目标,我们如何才能实现此功能? 当然,在sql server中运行时,上述查询会导致Error。

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

要在from子句中使用动态表,必须在外部运行命令DECLARE @sql NVARCHAR(MAX) DECLARE @dynamicSql NVARCHAR(MAX) SET @sql='SELECT * table' SET @dynamicSql ='SELECT t.*, a+b AS total_sum FROM ( '+@sql+' ) t' EXECUTE sp_executesql @dynamicSql : 在上面的例子中:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function


import numpy as np
import os
import cv2
import tensorflow as tf

tf.app.flags.DEFINE_string('directory', '/root/data2',
                           'Directory to download data files and write the '
                           'converted result')
FLAGS = tf.app.flags.FLAGS

def _int64_feature(value):
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))


def _bytes_feature(value):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def le_imagens(aux_folder):
    cont=0
    img=np.empty([1,28,28,1])
    for letter in os.listdir(aux_folder):
        folder=aux_folder+letter+"/"
        for imagem in os.listdir(folder):
            os.chdir(folder)
            img_temp=cv2.imread(imagem)
            img_temp = cv2.cvtColor(img_temp,cv2.COLOR_BGR2GRAY)
            img_temp= np.expand_dims(img_temp, axis=0)
            img_temp= np.expand_dims(img_temp, axis=3)
            img=np.vstack((img,img_temp))
            cont=cont+1
            print (cont)
    print (img.shape)
    return img

def calcula_label(letter):
    aux_label=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0"]
    label= np.zeros([1,36])
    cont=0
    for let in aux_label:
        if let==letter:
            label[0,cont]=1
        else:
            label[0,cont]=0
        cont=cont+1
    return label

def cria_array_labels(aux_folder):
    cont=0
    lab=np.empty([1,36])
    for letter in os.listdir(aux_folder):
        lab_temp=calcula_label(letter)
        folder=aux_folder+letter+"/"
        for imagem in os.listdir(folder):
            lab=np.vstack((lab,lab_temp))
            cont=cont+1
            print (cont)
    print (lab.shape)
    return lab


def convert_to(images, labels, name):
  #identifica quantidade de imagens e labels
  num_examples = labels.shape[0]
  if images.shape[0] != num_examples:
    raise ValueError("Images size %d does not match label size %d." %
                     (images.shape[0], num_examples))
  #pega parametros da imagem
  rows = images.shape[1]
  cols = images.shape[2]
  depth = 1

   #cria nome do arquivo de saida-acho que todas as imagens vao ser escritas aqui
  filename = os.path.join(FLAGS.directory, name + '.tfrecords')
  print('Writing', filename)
  writer = tf.python_io.TFRecordWriter(filename)
  #faz um loop para cada uma das imagens
  for index in range(num_examples):
    #converte a imagem para string
    image_raw = images[index].tostring()
    labels_raw = labels[index].tostring()
    #aloca no exemplo as dimensoes da img, o label e a imagem convertida
    example = tf.train.Example(features=tf.train.Features(feature={
        'height': _int64_feature(rows),
        'width': _int64_feature(cols),
        'depth': _int64_feature(depth),
        'label': _bytes_feature(labels_raw),
        'image_raw': _bytes_feature(image_raw)}))
    #escreve o exemplo
    writer.write(example.SerializeToString())
  writer.close()

def main(argv):
    #Train
    aux_folder="/root/captchas/captchas_lft/"
    img_treino=le_imagens(aux_folder)
    lab_treino=cria_array_labels(aux_folder)
    print ("Base de Treino Preparada")

    #Cross Validation
    aux_folder="/root/captchas/captchas_lfcv/"
    img_cv=le_imagens(aux_folder)
    lab_cv=cria_array_labels(aux_folder)
    print ("Base de CV Preparada")

    #Test Set
    aux_folder="/root/captchas/captchas_lfts/"
    img_ts=le_imagens(aux_folder)
    lab_ts=cria_array_labels(aux_folder)
    print ("Base de Teste Preparada")

    convert_to(img_treino, lab_treino, 'train')
    convert_to(img_cv, lab_cv, 'validation')
    convert_to(img_ts, lab_ts, 'test')

if __name__ == '__main__':
  tf.app.run()

答案 1 :(得分:1)

在SQL Server中,SQL语句在数据库第一次看到时编译。这意味着任何可以改变生成的代码的东西都不是参数。这反过来意味着您不能使用参数...

  • 表名称
  • 加入表达式
  • 列名称
  • where子句
  • 按条款订购

事实上,你可以说你或多或少地局限于使用......的参数。

  • 比较中的字面值MyColumn = @Param1
  • 精选语句中的文字值SELECT @Param2
  • 插入/更新语句中的文字值SET Column = @Param3
  • 热门,限制和提取条款SELECT TOP @Param4

如其他地方所述,解决方法是将SQL创建为字符串,然后将该字符串传递给sp_executesql

深注:

SQL通常编译为中间语言。可以将此中间语言视为XML。参见"执行计划"了解更多信息。

在SQL Server 2014中,存储过程可以转换为C ++代码,然后编译为机器语言。这样做有很多限制,在这里讨论太多了。