我正在处理一个应该在远程表中插入或更新行的存储过程。我尝试使用MERGE,但是当目标表是远程时,无法使用MERGE。
有人可以告诉我如何在sproc中进行更新?我是否需要先将记录读入临时表,然后比较这些值?我有兴趣更新的列值是FlagValue。
更新
我能够在另一台服务器上创建链接服务器并翻转目标和源。
我正在整理一个使用MERGE的存储过程,我想知道是否有人可以帮我查看代码并让我知道它是否正常。如果sku已经驻留在目标表中但是FlagValue值不同,则代码基本上必须更新FlagValue列,并且它必须插入也限制在USING()内的SELECT作为SOURCE的记录,而不是全部插入表产品中的记录。
更新的T-SQL:
ALTER PROCEDURE [dbo].[mn_RecordInfo_Upsert]
AS
BEGIN
--Synchronize the target table with refreshed data from source table
MERGE [dbo].[RecordInfo] AS [t]
USING
( SELECT TOP 100 PERCENT
[p].[ProductID]
, [p].[Flag]
FROM
[server].[db].[dbo].[Product] [p] -- Remote linked server table
WHERE
(
[Category] = 2
OR [Description] = 'This type of product' )
AND LEN([ProductID]) = 10
AND [ProductID] LIKE 'P0%'
ORDER BY
[Date] DESC
) AS [s]
ON ( [t].[PID] = [s].[ProductID] )
--When records are matched, update the records if there is any change
WHEN MATCHED AND [t].[Flag] <> [s].[Flag]
AND [t].[PID] = [s].[ProductID] THEN
UPDATE SET
[t].[Flag] = [s].[Flag]
--When no records are matched, insert the incoming records from source table to target table
WHEN NOT MATCHED BY TARGET THEN
INSERT
(
[PID]
, [Flag] )
VALUES (
[s].[ProductID]
, [s].[Flag] )
--SELECT @@ROWCOUNT;
OUTPUT
$action AS [DMLAction]
, [inserted].*
, [deleted].*;
END;
感谢您的推荐。
答案 0 :(得分:1)
如果我理解你的问题只是你所写的内容做了你的想法吗?我相信它确实如此。尽管再次加入import numpy as np
import tensorflow as tf
import glob
import os
tf_record_dir = os.getcwd() + '/'
batch_size = 30
num_epochs = 100
filename = os.path.join(tf_record_dir, 'train.tfrecords')
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def gen_tf_record_files():
print ('Writing', filename)
writer = tf.python_io.TFRecordWriter(filename)
for index in range(1000):
example = tf.train.Example(features=tf.train.Features(feature={'image_id': _int64_feature(index)
}))
writer.write(example.SerializeToString())
writer.close()
def inputs():
tfRec_files_list = glob.glob(filename)
with tf.name_scope('input'):
filename_queue = tf.train.string_input_producer(tfRec_files_list, num_epochs=num_epochs, name='string_input_producer')
im_id = _read_and_decode(filename_queue)
min_after_dequeue = 10
capacity = min_after_dequeue + 3 * batch_size
im_ids = tf.train.shuffle_batch([im_id], batch_size=batch_size, num_threads=3,
capacity=capacity, enqueue_many=False, min_after_dequeue=min_after_dequeue, name='batching_shuffling')
return im_ids
def _read_and_decode(filename_queue):
# All of the bellow are symbolics
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example,
features={'image_id': tf.FixedLenFeature([], tf.int64)
})
im_id = tf.to_int32(features['image_id'], name='ToInt32')
return im_id
def main():
# initialize graph
gen_tf_record_files()
g = tf.Graph()
with g.as_default():
im_id = inputs()
if tf.__version__.split('.')[0] == "1":
init = tf.global_variables_initializer()
else:
init = tf.initialize_all_variables() #it is deprecated in TF 1.1
sess = tf.Session(config=tf.ConfigProto(log_device_placement=False))
with sess.as_default():
sess.run(init)
# Start the queue runners.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
im = sess.run(im_id)
main()
是多余的,但您的更新看起来还不错。单个合并语句中的所有不同语句(例如target.sku = source.sku
,when matched
,when not matched by source
)将使用在顶部声明的连接条件,因此您不需要指定它再次。另一件需要考虑的事情是when not matched by target
是否为空。如果是,请检查FlagValue
之后target.FlagValue != source.FlagValue
将返回错误。
至于你的插页,你是对的。它只会使用您定义的子查询的结果,并将其别名为null != null
(旁注,虽然MSDN喜欢将它们设为别名source
和source
,但我倾向于target
和s
因为他们不是保留关键字,并且在您输入时最终使用t
和source
作为实际关键字时避免混淆,因为例如,target
。重点是,您可以随意为它们添加别名;您不仅限于这两个关键字。)
如果您想了解执行过程中发生的事情,您可以做两件事。第一种是在最后使用when not matched by target
子句;像
OUTPUT
如果您发现...
(
[SOURCE].[SKU],
[SOURCE].[FlagValue]
)
output $action as DMLAction, inserted.*, deleted.*
笨拙地工作,第二种方法是考虑将这些语句写成两个单独的语句而不是MERGE
;一个MERGE
和一个insert
。在大多数情况下,update
无论如何都会这样做,因此您不会失去性能,而且通常更容易选择MERGE
或insert
声明而不是我update
的经验。
此外,在加入链接服务器时,我必须谨慎。有时它会表现得很好,但有时候它会完全自己做。如果远程表很大,您可能最终会扫描整个表并将其在链接服务器上进行管道传输,即使您不希望它获得任何接近本地表不良的计划的任何内容。